mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Merge remote branch 'mainstream/master'
This commit is contained in:
23
Gemfile
23
Gemfile
@@ -1,17 +1,20 @@
|
||||
gem "rake", ">= 0.8.7"
|
||||
gem "mocha", ">= 0.9.8"
|
||||
gem "ruby-debug", ">= 0.10.3" if RUBY_VERSION < '1.9'
|
||||
path File.expand_path('..', __FILE__)
|
||||
source :gemcutter
|
||||
|
||||
gem "rails", "3.0.pre", :path => "railties"
|
||||
%w(activesupport activemodel actionpack actionmailer activerecord activeresource).each do |lib|
|
||||
gem lib, '3.0.pre', :path => lib
|
||||
gem "rails", "3.0.pre"
|
||||
|
||||
gem "rake", ">= 0.8.7"
|
||||
gem "mocha", ">= 0.9.8"
|
||||
|
||||
if RUBY_VERSION < '1.9'
|
||||
gem "ruby-debug", ">= 0.10.3"
|
||||
end
|
||||
|
||||
# AR
|
||||
gem "arel", "0.2.pre", :git => "git://github.com/rails/arel.git"
|
||||
gem "arel", ">= 0.2.0"
|
||||
gem "sqlite3-ruby", ">= 1.2.5"
|
||||
|
||||
only :test do
|
||||
group :test do
|
||||
gem "pg", ">= 0.8.0"
|
||||
gem "mysql", ">= 2.8.1"
|
||||
end
|
||||
@@ -21,8 +24,6 @@ gem "rack-test", "0.5.3"
|
||||
gem "RedCloth", ">= 4.2.2"
|
||||
|
||||
if ENV['CI']
|
||||
disable_system_gems
|
||||
|
||||
gem "nokogiri", ">= 1.4.0"
|
||||
gem "memcache-client", ">= 1.7.6"
|
||||
|
||||
@@ -34,5 +35,3 @@ if ENV['CI']
|
||||
gem "test-unit", ">= 2.0.5"
|
||||
end
|
||||
end
|
||||
|
||||
disable_system_gems
|
||||
|
||||
1
Rakefile
1
Rakefile
@@ -38,7 +38,6 @@ Rake::GemPackageTask.new(spec) do |pkg|
|
||||
end
|
||||
|
||||
task :install => :gem do
|
||||
system %(cd arel && gem build arel.gemspec && gem install arel-0.2.pre.gem --no-ri --no-rdoc --ignore-dependencies)
|
||||
system %(cd rack && rake gem VERSION=1.0.2.pre && gem install rack-1.0.2.pre.gem --no-ri --no-rdoc --ignore-dependencies)
|
||||
(PROJECTS - ["railties"]).each do |project|
|
||||
puts "INSTALLING #{project}"
|
||||
|
||||
@@ -268,13 +268,13 @@ module ActionMailer #:nodoc:
|
||||
|
||||
private_class_method :new #:nodoc:
|
||||
|
||||
extlib_inheritable_accessor :default_params
|
||||
class_attribute :default_params
|
||||
self.default_params = {
|
||||
:mime_version => "1.0",
|
||||
:charset => "utf-8",
|
||||
:content_type => "text/plain",
|
||||
:parts_order => [ "text/plain", "text/enriched", "text/html" ]
|
||||
}
|
||||
}.freeze
|
||||
|
||||
class << self
|
||||
|
||||
@@ -284,9 +284,9 @@ module ActionMailer #:nodoc:
|
||||
attr_writer :mailer_name
|
||||
alias :controller_path :mailer_name
|
||||
|
||||
def default(value=nil)
|
||||
self.default_params.merge!(value) if value
|
||||
self.default_params
|
||||
def default(value = nil)
|
||||
self.default_params = default_params.merge(value).freeze if value
|
||||
default_params
|
||||
end
|
||||
|
||||
# Receives a raw email, parses it into an email object, decodes it,
|
||||
|
||||
@@ -7,8 +7,7 @@ module ActionMailer
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor :delivery_methods, :delivery_method,
|
||||
:instance_writer => false
|
||||
class_attribute :delivery_methods, :delivery_method
|
||||
|
||||
# Do not make this inheritable, because we always want it to propagate
|
||||
cattr_accessor :raise_delivery_errors
|
||||
@@ -17,7 +16,7 @@ module ActionMailer
|
||||
cattr_accessor :perform_deliveries
|
||||
self.perform_deliveries = true
|
||||
|
||||
self.delivery_methods = {}
|
||||
self.delivery_methods = {}.freeze
|
||||
self.delivery_method = :smtp
|
||||
|
||||
add_delivery_method :smtp, Mail::SMTP,
|
||||
@@ -53,12 +52,9 @@ module ActionMailer
|
||||
# :arguments => '-i -t'
|
||||
#
|
||||
def add_delivery_method(symbol, klass, default_options={})
|
||||
unless respond_to?(:"#{symbol}_settings")
|
||||
extlib_inheritable_accessor(:"#{symbol}_settings", :instance_writer => false)
|
||||
end
|
||||
|
||||
class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
|
||||
send(:"#{symbol}_settings=", default_options)
|
||||
self.delivery_methods[symbol.to_sym] = klass
|
||||
self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
|
||||
end
|
||||
|
||||
def wrap_delivery_behavior(mail, method=nil) #:nodoc:
|
||||
@@ -87,4 +83,4 @@ module ActionMailer
|
||||
self.class.wrap_delivery_behavior(message, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,7 +47,7 @@ module ActionMailer
|
||||
end
|
||||
|
||||
def template_root=(root)
|
||||
ActiveSupport::Deprecation.warn "template_root= is deprecated, use view_paths.unshift instead", caller[0,2]
|
||||
ActiveSupport::Deprecation.warn "template_root= is deprecated, use prepend_view_path instead", caller[0,2]
|
||||
self.view_paths = ActionView::Base.process_view_paths(root)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
begin
|
||||
require File.expand_path('../../../vendor/gems/environment', __FILE__)
|
||||
rescue LoadError
|
||||
end
|
||||
require File.expand_path('../../../load_paths', __FILE__)
|
||||
|
||||
lib = File.expand_path('../../lib', __FILE__)
|
||||
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
||||
|
||||
require 'rubygems'
|
||||
require 'test/unit'
|
||||
require 'action_mailer'
|
||||
require 'action_mailer/test_case'
|
||||
|
||||
# Show backtraces for deprecated behavior for quicker cleanup.
|
||||
ActiveSupport::Deprecation.debug = true
|
||||
|
||||
@@ -81,8 +81,8 @@ class BaseTest < ActiveSupport::TestCase
|
||||
|
||||
def different_template(template_name='')
|
||||
mail do |format|
|
||||
format.text { render :template => template_name }
|
||||
format.html { render :template => template_name }
|
||||
format.text { render :template => "#{mailer_name}/#{template_name}" }
|
||||
format.html { render :template => "#{mailer_name}/#{template_name}" }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -254,7 +254,7 @@ class BaseTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "subject gets default from I18n" do
|
||||
BaseMailer.default[:subject] = nil
|
||||
BaseMailer.default :subject => nil
|
||||
email = BaseMailer.welcome(:subject => nil)
|
||||
assert_equal "Welcome", email.subject
|
||||
|
||||
@@ -331,22 +331,24 @@ class BaseTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "implicit multipart with several view paths uses the first one with template" do
|
||||
old = BaseMailer.view_paths
|
||||
begin
|
||||
BaseMailer.view_paths.unshift(File.join(FIXTURE_LOAD_PATH, "another.path"))
|
||||
BaseMailer.view_paths = [File.join(FIXTURE_LOAD_PATH, "another.path")] + old.dup
|
||||
email = BaseMailer.welcome
|
||||
assert_equal("Welcome from another path", email.body.encoded)
|
||||
ensure
|
||||
BaseMailer.view_paths.shift
|
||||
BaseMailer.view_paths = old
|
||||
end
|
||||
end
|
||||
|
||||
test "implicit multipart with inexistent templates uses the next view path" do
|
||||
old = BaseMailer.view_paths
|
||||
begin
|
||||
BaseMailer.view_paths.unshift(File.join(FIXTURE_LOAD_PATH, "unknown"))
|
||||
BaseMailer.view_paths = [File.join(FIXTURE_LOAD_PATH, "unknown")] + old.dup
|
||||
email = BaseMailer.welcome
|
||||
assert_equal("Welcome", email.body.encoded)
|
||||
ensure
|
||||
BaseMailer.view_paths.shift
|
||||
BaseMailer.view_paths = old
|
||||
end
|
||||
end
|
||||
|
||||
@@ -503,16 +505,10 @@ class BaseTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
def with_default(klass, new_values)
|
||||
hash = klass.default
|
||||
old_values = {}
|
||||
new_values.each do |key, value|
|
||||
old_values[key] = hash[key]
|
||||
hash[key] = value
|
||||
end
|
||||
old = klass.default_params
|
||||
klass.default(new_values)
|
||||
yield
|
||||
ensure
|
||||
old_values.each do |key, value|
|
||||
hash[key] = value
|
||||
end
|
||||
klass.default_params = old
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,7 +45,9 @@ class CustomDeliveryMethodsTest < ActiveSupport::TestCase
|
||||
|
||||
def teardown
|
||||
ActionMailer::Base.delivery_method = @old_delivery_method
|
||||
ActionMailer::Base.delivery_methods.delete(:custom)
|
||||
new = ActionMailer::Base.delivery_methods.dup
|
||||
new.delete(:custom)
|
||||
ActionMailer::Base.delivery_methods = new
|
||||
end
|
||||
|
||||
test "allow to add custom delivery method" do
|
||||
@@ -167,4 +169,4 @@ class MailDeliveryTest < ActiveSupport::TestCase
|
||||
assert_equal(0, DeliveryMailer.deliveries.length)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
require 'active_support/dependencies'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
module AbstractController
|
||||
module Helpers
|
||||
@@ -12,10 +14,10 @@ module AbstractController
|
||||
end
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor(:_helpers) { Module.new }
|
||||
extlib_inheritable_accessor(:_helper_serial) do
|
||||
AbstractController::Helpers.next_serial
|
||||
end
|
||||
class_attribute :_helpers, :_helper_serial
|
||||
delegate :_helpers, :to => :'self.class'
|
||||
self._helpers = Module.new
|
||||
self._helper_serial = ::AbstractController::Helpers.next_serial
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
module AbstractController
|
||||
# Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
|
||||
# repeated setups. The inclusion pattern has pages that look like this:
|
||||
@@ -161,8 +164,9 @@ module AbstractController
|
||||
include Rendering
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor(:_layout_conditions) { Hash.new }
|
||||
extlib_inheritable_accessor(:_action_has_layout) { Hash.new }
|
||||
class_attribute :_layout_conditions
|
||||
delegate :_layout_conditions, :to => :'self.class'
|
||||
self._layout_conditions = {}
|
||||
_write_layout_method
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
require "abstract_controller/base"
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
require 'active_support/core_ext/array/wrap'
|
||||
|
||||
module AbstractController
|
||||
class DoubleRenderError < Error
|
||||
@@ -13,8 +16,9 @@ module AbstractController
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor :_view_paths
|
||||
self._view_paths ||= ActionView::PathSet.new
|
||||
class_attribute :_view_paths
|
||||
delegate :_view_paths, :to => :'self.class'
|
||||
self._view_paths = ActionView::PathSet.new
|
||||
end
|
||||
|
||||
# An instance of a view class. The default view class is ActionView::Base
|
||||
@@ -156,7 +160,6 @@ module AbstractController
|
||||
elsif options.key?(:file)
|
||||
options[:_template_name] = options[:file]
|
||||
end
|
||||
|
||||
name = (options[:_template_name] || options[:action] || action_name).to_s
|
||||
options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty?
|
||||
|
||||
@@ -201,7 +204,7 @@ module AbstractController
|
||||
# the default view path. You may also provide a custom view path
|
||||
# (see ActionView::ViewPathSet for more information)
|
||||
def append_view_path(path)
|
||||
self.view_paths << path
|
||||
self.view_paths = view_paths.dup + Array.wrap(path)
|
||||
end
|
||||
|
||||
# Prepend a path to the list of view paths for this controller.
|
||||
@@ -212,12 +215,12 @@ module AbstractController
|
||||
# (see ActionView::ViewPathSet for more information)
|
||||
def prepend_view_path(path)
|
||||
clear_template_caches!
|
||||
self.view_paths.unshift(path)
|
||||
self.view_paths = Array.wrap(path) + view_paths.dup
|
||||
end
|
||||
|
||||
# A list of all of the default view paths for this controller.
|
||||
def view_paths
|
||||
self._view_paths
|
||||
_view_paths
|
||||
end
|
||||
|
||||
# Set the view paths.
|
||||
@@ -228,7 +231,8 @@ module AbstractController
|
||||
def view_paths=(paths)
|
||||
clear_template_caches!
|
||||
self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths)
|
||||
_view_paths.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'active_support/core_ext/class/inheritable_attributes'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController
|
||||
# ActionController::Metal provides a way to get a valid Rack application from a controller.
|
||||
@@ -90,7 +90,12 @@ module ActionController
|
||||
end
|
||||
end
|
||||
|
||||
extlib_inheritable_accessor(:middleware_stack) { ActionDispatch::MiddlewareStack.new }
|
||||
class_attribute :middleware_stack
|
||||
self.middleware_stack = ActionDispatch::MiddlewareStack.new
|
||||
|
||||
def self.inherited(base)
|
||||
self.middleware_stack = base.middleware_stack.dup
|
||||
end
|
||||
|
||||
def self.use(*args)
|
||||
middleware_stack.use(*args)
|
||||
|
||||
@@ -15,9 +15,6 @@ module ActionController
|
||||
cattr_accessor :session_options
|
||||
self.session_options = {}
|
||||
|
||||
cattr_accessor :allow_concurrency
|
||||
self.allow_concurrency = false
|
||||
|
||||
cattr_accessor :relative_url_root
|
||||
self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
|
||||
|
||||
@@ -44,9 +41,6 @@ module ActionController
|
||||
|
||||
self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : ""
|
||||
|
||||
cattr_accessor :consider_all_requests_local
|
||||
self.consider_all_requests_local = true
|
||||
|
||||
# Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
|
||||
# and images to a dedicated asset server away from the main web server. Example:
|
||||
# ActionController::Base.asset_host = "http://assets.example.com"
|
||||
@@ -74,6 +68,25 @@ module ActionController
|
||||
|
||||
module ClassMethods
|
||||
def consider_all_requests_local
|
||||
ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " <<
|
||||
"use Rails.application.config.consider_all_requests_local instead"
|
||||
Rails.application.config.consider_all_requests_local
|
||||
end
|
||||
|
||||
def consider_all_requests_local=(value)
|
||||
ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is no longer effective. " <<
|
||||
"Please configure it on your application with config.consider_all_requests_local="
|
||||
end
|
||||
|
||||
def allow_concurrency
|
||||
ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " <<
|
||||
"use Rails.application.config.allow_concurrency instead"
|
||||
Rails.application.config.allow_concurrency
|
||||
end
|
||||
|
||||
def allow_concurrency=(value)
|
||||
ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is no longer effective. " <<
|
||||
"Please configure it on your application with config.allow_concurrency="
|
||||
end
|
||||
|
||||
def rescue_action(env)
|
||||
@@ -86,6 +99,9 @@ module ActionController
|
||||
end
|
||||
end
|
||||
|
||||
delegate :consider_all_requests_local, :consider_all_requests_local=,
|
||||
:allow_concurrency, :allow_concurrency=, :to => :"self.class"
|
||||
|
||||
def render_to_body(options)
|
||||
if options.is_a?(Hash) && options.key?(:template)
|
||||
options[:template].sub!(/^\//, '')
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController
|
||||
# The Rails framework provides a large number of helpers for working with +assets+, +dates+, +forms+,
|
||||
# +numbers+ and model objects, to name a few. These helpers are available to all templates
|
||||
@@ -50,7 +52,7 @@ module ActionController
|
||||
include AbstractController::Helpers
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor(:helpers_path)
|
||||
class_attribute :helpers_path
|
||||
self.helpers_path = []
|
||||
end
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController
|
||||
# ActionController::HideActions adds the ability to prevent public methods on a controller
|
||||
# to be called as actions.
|
||||
@@ -5,7 +7,8 @@ module ActionController
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor(:hidden_actions) { Set.new }
|
||||
class_attribute :hidden_actions
|
||||
self.hidden_actions = Set.new
|
||||
end
|
||||
|
||||
private
|
||||
@@ -14,7 +17,7 @@ module ActionController
|
||||
# action name is in the list of hidden actions.
|
||||
def action_method?(action_name)
|
||||
self.class.visible_action?(action_name) do
|
||||
!hidden_actions.include?(action_name) && super
|
||||
!self.class.hidden_actions.include?(action_name) && super
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,7 +27,7 @@ module ActionController
|
||||
# ==== Parameters
|
||||
# *args<#to_s>:: A list of actions
|
||||
def hide_action(*args)
|
||||
hidden_actions.merge(args.map! {|a| a.to_s })
|
||||
self.hidden_actions = hidden_actions.dup.merge(args.map(&:to_s))
|
||||
end
|
||||
|
||||
def inherited(klass)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
require 'abstract_controller/collector'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
module MimeResponds #:nodoc:
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor :responder, :mimes_for_respond_to, :instance_writer => false
|
||||
class_attribute :responder, :mimes_for_respond_to
|
||||
self.responder = ActionController::Responder
|
||||
clear_respond_to
|
||||
end
|
||||
@@ -38,18 +39,20 @@ module ActionController #:nodoc:
|
||||
only_actions = Array(options.delete(:only))
|
||||
except_actions = Array(options.delete(:except))
|
||||
|
||||
new = mimes_for_respond_to.dup
|
||||
mimes.each do |mime|
|
||||
mime = mime.to_sym
|
||||
mimes_for_respond_to[mime] = {}
|
||||
mimes_for_respond_to[mime][:only] = only_actions unless only_actions.empty?
|
||||
mimes_for_respond_to[mime][:except] = except_actions unless except_actions.empty?
|
||||
new[mime] = {}
|
||||
new[mime][:only] = only_actions unless only_actions.empty?
|
||||
new[mime][:except] = except_actions unless except_actions.empty?
|
||||
end
|
||||
self.mimes_for_respond_to = new.freeze
|
||||
end
|
||||
|
||||
# Clear all mimes in respond_to.
|
||||
#
|
||||
def clear_respond_to
|
||||
self.mimes_for_respond_to = ActiveSupport::OrderedHash.new
|
||||
self.mimes_for_respond_to = ActiveSupport::OrderedHash.new.freeze
|
||||
end
|
||||
end
|
||||
|
||||
@@ -218,12 +221,12 @@ module ActionController #:nodoc:
|
||||
#
|
||||
def respond_with(*resources, &block)
|
||||
raise "In order to use respond_with, first you need to declare the formats your " <<
|
||||
"controller responds to in the class level" if mimes_for_respond_to.empty?
|
||||
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
|
||||
|
||||
if response = retrieve_response_from_mimes(&block)
|
||||
options = resources.extract_options!
|
||||
options.merge!(:default_response => response)
|
||||
(options.delete(:responder) || responder).call(self, resources, options)
|
||||
(options.delete(:responder) || self.class.responder).call(self, resources, options)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -235,8 +238,8 @@ module ActionController #:nodoc:
|
||||
def collect_mimes_from_class_level #:nodoc:
|
||||
action = action_name.to_sym
|
||||
|
||||
mimes_for_respond_to.keys.select do |mime|
|
||||
config = mimes_for_respond_to[mime]
|
||||
self.class.mimes_for_respond_to.keys.select do |mime|
|
||||
config = self.class.mimes_for_respond_to[mime]
|
||||
|
||||
if config[:except]
|
||||
!config[:except].include?(action)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController
|
||||
def self.add_renderer(key, &block)
|
||||
Renderers.add(key, &block)
|
||||
@@ -7,8 +9,8 @@ module ActionController
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor :_renderers
|
||||
self._renderers = {}
|
||||
class_attribute :_renderers
|
||||
self._renderers = {}.freeze
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
@@ -30,9 +32,11 @@ module ActionController
|
||||
end
|
||||
|
||||
def use_renderers(*args)
|
||||
new = _renderers.dup
|
||||
args.each do |key|
|
||||
_renderers[key] = RENDERERS[key]
|
||||
new[key] = RENDERERS[key]
|
||||
end
|
||||
self._renderers = new.freeze
|
||||
_write_render_options
|
||||
end
|
||||
alias use_renderer use_renderers
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
class InvalidAuthenticityToken < ActionControllerError #:nodoc:
|
||||
end
|
||||
@@ -13,7 +15,7 @@ module ActionController #:nodoc:
|
||||
cattr_accessor :request_forgery_protection_token
|
||||
|
||||
# Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
|
||||
extlib_inheritable_accessor :allow_forgery_protection
|
||||
class_attribute :allow_forgery_protection
|
||||
self.allow_forgery_protection = true
|
||||
|
||||
helper_method :form_authenticity_token
|
||||
@@ -107,7 +109,7 @@ module ActionController #:nodoc:
|
||||
end
|
||||
|
||||
def protect_against_forgery?
|
||||
allow_forgery_protection
|
||||
self.class.allow_forgery_protection
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ module ActionController
|
||||
|
||||
include RackDelegation
|
||||
|
||||
# OMG MEGA HAX
|
||||
# TODO: Clean this up
|
||||
def process_with_new_base_test(request, response)
|
||||
@_request = request
|
||||
@_response = response
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController
|
||||
# In <b>routes.rb</b> one defines URL-to-controller mappings, but the reverse
|
||||
# is also possible: an URL can be generated from one of your routing definitions.
|
||||
@@ -85,9 +87,8 @@ module ActionController
|
||||
|
||||
included do
|
||||
ActionController::Routing::Routes.install_helpers(self)
|
||||
extlib_inheritable_accessor :default_url_options,
|
||||
:instance_writer => false, :instance_reader => false
|
||||
self.default_url_options ||= {}
|
||||
class_attribute :default_url_options
|
||||
self.default_url_options = {}
|
||||
end
|
||||
|
||||
# Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in
|
||||
|
||||
@@ -35,7 +35,6 @@ module ActionView
|
||||
autoload :Context
|
||||
autoload :Template
|
||||
autoload :Helpers
|
||||
autoload :SafeBuffer
|
||||
|
||||
autoload_under "render" do
|
||||
autoload :Partials
|
||||
@@ -56,7 +55,7 @@ module ActionView
|
||||
autoload :TestCase, 'action_view/test_case'
|
||||
end
|
||||
|
||||
require 'action_view/erb/util'
|
||||
require 'active_support/core_ext/string/output_safety'
|
||||
require 'action_view/base'
|
||||
|
||||
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'active_support/core_ext/module/attr_internal'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionView #:nodoc:
|
||||
class ActionViewError < StandardError #:nodoc:
|
||||
@@ -244,7 +245,7 @@ module ActionView #:nodoc:
|
||||
ActionView::PathSet.new(Array(value))
|
||||
end
|
||||
|
||||
extlib_inheritable_accessor :helpers
|
||||
class_attribute :helpers
|
||||
attr_reader :helpers
|
||||
|
||||
def self.for_controller(controller)
|
||||
@@ -284,7 +285,7 @@ module ActionView #:nodoc:
|
||||
@helpers = self.class.helpers || Module.new
|
||||
|
||||
@_controller = controller
|
||||
@_content_for = Hash.new {|h,k| h[k] = ActionView::SafeBuffer.new }
|
||||
@_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new }
|
||||
@_virtual_path = nil
|
||||
self.view_paths = view_paths
|
||||
end
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
require 'erb'
|
||||
|
||||
class ERB
|
||||
module Util
|
||||
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
||||
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
||||
|
||||
# A utility method for escaping HTML tag characters.
|
||||
# This method is also aliased as <tt>h</tt>.
|
||||
#
|
||||
# In your ERb templates, use this method to escape any unsafe content. For example:
|
||||
# <%=h @person.name %>
|
||||
#
|
||||
# ==== Example:
|
||||
# puts html_escape("is a > 0 & a < 10?")
|
||||
# # => is a > 0 & a < 10?
|
||||
def html_escape(s)
|
||||
s = s.to_s
|
||||
if s.html_safe?
|
||||
s
|
||||
else
|
||||
s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }.html_safe!
|
||||
end
|
||||
end
|
||||
|
||||
undef :h
|
||||
alias h html_escape
|
||||
|
||||
module_function :html_escape
|
||||
module_function :h
|
||||
|
||||
# A utility method for escaping HTML entities in JSON strings.
|
||||
# This method is also aliased as <tt>j</tt>.
|
||||
#
|
||||
# In your ERb templates, use this method to escape any HTML entities:
|
||||
# <%=j @person.to_json %>
|
||||
#
|
||||
# ==== Example:
|
||||
# puts json_escape("is a > 0 & a < 10?")
|
||||
# # => is a \u003E 0 \u0026 a \u003C 10?
|
||||
def json_escape(s)
|
||||
s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
|
||||
end
|
||||
|
||||
alias j json_escape
|
||||
module_function :j
|
||||
module_function :json_escape
|
||||
end
|
||||
end
|
||||
@@ -6,7 +6,7 @@ require 'active_support/core_ext/kernel/reporting'
|
||||
|
||||
module ActionView
|
||||
class Base
|
||||
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe! }
|
||||
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe }
|
||||
cattr_accessor :field_error_proc
|
||||
end
|
||||
|
||||
@@ -86,12 +86,11 @@ module ActionView
|
||||
submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize
|
||||
|
||||
contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil)
|
||||
contents << hidden_field(record_name, :id) unless record.new_record?
|
||||
contents << all_input_tags(record, record_name, options)
|
||||
contents.safe_concat hidden_field(record_name, :id) unless record.new_record?
|
||||
contents.safe_concat all_input_tags(record, record_name, options)
|
||||
yield contents if block_given?
|
||||
contents << submit_tag(submit_value)
|
||||
contents << '</form>'
|
||||
contents.html_safe!
|
||||
contents.safe_concat submit_tag(submit_value)
|
||||
contents.safe_concat('</form>')
|
||||
end
|
||||
|
||||
# Returns a string containing the error message attached to the +method+ on the +object+ if one exists.
|
||||
|
||||
@@ -293,7 +293,7 @@ module ActionView
|
||||
else
|
||||
sources = expand_javascript_sources(sources, recursive)
|
||||
ensure_javascript_sources!(sources) if cache
|
||||
sources.collect { |source| javascript_src_tag(source, options) }.join("\n").html_safe!
|
||||
sources.collect { |source| javascript_src_tag(source, options) }.join("\n").html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -444,7 +444,7 @@ module ActionView
|
||||
else
|
||||
sources = expand_stylesheet_sources(sources, recursive)
|
||||
ensure_stylesheet_sources!(sources) if cache
|
||||
sources.collect { |source| stylesheet_tag(source, options) }.join("\n").html_safe!
|
||||
sources.collect { |source| stylesheet_tag(source, options) }.join("\n").html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -588,7 +588,7 @@ module ActionView
|
||||
|
||||
if sources.is_a?(Array)
|
||||
content_tag("video", options) do
|
||||
sources.map { |source| tag("source", :src => source) }.join.html_safe!
|
||||
sources.map { |source| tag("source", :src => source) }.join.html_safe
|
||||
end
|
||||
else
|
||||
options[:src] = path_to_video(sources)
|
||||
|
||||
@@ -143,7 +143,7 @@ module ActionView
|
||||
# Defaults to a new empty string.
|
||||
def with_output_buffer(buf = nil) #:nodoc:
|
||||
unless buf
|
||||
buf = ActionView::SafeBuffer.new
|
||||
buf = ActiveSupport::SafeBuffer.new
|
||||
buf.force_encoding(output_buffer.encoding) if buf.respond_to?(:force_encoding)
|
||||
end
|
||||
self.output_buffer, old_buffer = buf, output_buffer
|
||||
|
||||
@@ -616,7 +616,7 @@ module ActionView
|
||||
|
||||
build_selects_from_types(order)
|
||||
else
|
||||
"#{select_date}#{@options[:datetime_separator]}#{select_time}".html_safe!
|
||||
"#{select_date}#{@options[:datetime_separator]}#{select_time}".html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -835,7 +835,7 @@ module ActionView
|
||||
select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
|
||||
select_html << select_options_as_html.to_s
|
||||
|
||||
(content_tag(:select, select_html, select_options) + "\n").html_safe!
|
||||
(content_tag(:select, select_html, select_options) + "\n").html_safe
|
||||
end
|
||||
|
||||
# Builds a prompt option tag with supplied options or from default options
|
||||
@@ -865,7 +865,7 @@ module ActionView
|
||||
:id => input_id_from_type(type),
|
||||
:name => input_name_from_type(type),
|
||||
:value => value
|
||||
}) + "\n").html_safe!
|
||||
}) + "\n").html_safe
|
||||
end
|
||||
|
||||
# Returns the name attribute for the input tag
|
||||
@@ -896,7 +896,7 @@ module ActionView
|
||||
separator = separator(type) unless type == order.first # don't add on last field
|
||||
select.insert(0, separator.to_s + send("select_#{type}").to_s)
|
||||
end
|
||||
select.html_safe!
|
||||
select.html_safe
|
||||
end
|
||||
|
||||
# Returns the separator for a given datetime component
|
||||
@@ -916,15 +916,15 @@ module ActionView
|
||||
|
||||
class InstanceTag #:nodoc:
|
||||
def to_date_select_tag(options = {}, html_options = {})
|
||||
datetime_selector(options, html_options).select_date.html_safe!
|
||||
datetime_selector(options, html_options).select_date.html_safe
|
||||
end
|
||||
|
||||
def to_time_select_tag(options = {}, html_options = {})
|
||||
datetime_selector(options, html_options).select_time.html_safe!
|
||||
datetime_selector(options, html_options).select_time.html_safe
|
||||
end
|
||||
|
||||
def to_datetime_select_tag(options = {}, html_options = {})
|
||||
datetime_selector(options, html_options).select_datetime.html_safe!
|
||||
datetime_selector(options, html_options).select_datetime.html_safe
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -27,10 +27,10 @@ module ActionView
|
||||
def debug(object)
|
||||
begin
|
||||
Marshal::dump(object)
|
||||
"<pre class='debug_dump'>#{h(object.to_yaml).gsub(" ", " ")}</pre>".html_safe!
|
||||
"<pre class='debug_dump'>#{h(object.to_yaml).gsub(" ", " ")}</pre>".html_safe
|
||||
rescue Exception => e # errors from Marshal or YAML
|
||||
# Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback
|
||||
"<code class='debug_dump'>#{h(object.inspect)}</code>".html_safe!
|
||||
"<code class='debug_dump'>#{h(object.inspect)}</code>".html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -225,6 +225,33 @@ module ActionView
|
||||
# ...
|
||||
# <% end %>
|
||||
#
|
||||
# === Unobtrusive JavaScript
|
||||
#
|
||||
# Specifying:
|
||||
#
|
||||
# :remote => true
|
||||
#
|
||||
# in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its
|
||||
# behaviour. The expected default behaviour is an XMLHttpRequest in the background instead of the regular
|
||||
# POST arrangement, but ultimately the behaviour is the choice of the JavaScript driver implementor.
|
||||
# Even though it's using JavaScript to serialize the form elements, the form submission will work just like
|
||||
# a regular submission as viewed by the receiving side (all elements available in <tt>params</tt>).
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# <% form_for(:post, @post, :remote => true, :html => { :id => 'create-post', :method => :put }) do |f| %>
|
||||
# ...
|
||||
# <% end %>
|
||||
#
|
||||
# The HTML generated for this would be:
|
||||
#
|
||||
# <form action='http://www.example.com' id='create-post' method='post' data-remote='true'>
|
||||
# <div style='margin:0;padding:0;display:inline'>
|
||||
# <input name='_method' type='hidden' value='put' />
|
||||
# </div>
|
||||
# ...
|
||||
# </form>
|
||||
#
|
||||
# === Customized form builders
|
||||
#
|
||||
# You can also build forms using a customized FormBuilder class. Subclass
|
||||
@@ -280,9 +307,11 @@ module ActionView
|
||||
args.unshift object
|
||||
end
|
||||
|
||||
options[:html][:remote] = true if options.delete(:remote)
|
||||
|
||||
concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
|
||||
fields_for(object_name, *(args << options), &proc)
|
||||
concat('</form>'.html_safe!)
|
||||
safe_concat('</form>')
|
||||
end
|
||||
|
||||
def apply_form_for_options!(object_or_array, options) #:nodoc:
|
||||
@@ -850,7 +879,7 @@ module ActionView
|
||||
end
|
||||
hidden = tag("input", "name" => options["name"], "type" => "hidden", "value" => options['disabled'] && checked ? checked_value : unchecked_value)
|
||||
checkbox = tag("input", options)
|
||||
(hidden + checkbox).html_safe!
|
||||
(hidden + checkbox).html_safe
|
||||
end
|
||||
|
||||
def to_boolean_select_tag(options = {})
|
||||
|
||||
@@ -296,7 +296,7 @@ module ActionView
|
||||
options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}>#{html_escape(text.to_s)}</option>)
|
||||
end
|
||||
|
||||
options_for_select.join("\n").html_safe!
|
||||
options_for_select.join("\n").html_safe
|
||||
end
|
||||
|
||||
# Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the
|
||||
|
||||
@@ -19,6 +19,8 @@ module ActionView
|
||||
# If "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
|
||||
# is added to simulate the verb over post.
|
||||
# * A list of parameters to feed to the URL the form will be posted to.
|
||||
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
|
||||
# submit behaviour. By default this behaviour is an ajax submit.
|
||||
#
|
||||
# ==== Examples
|
||||
# form_tag('/posts')
|
||||
@@ -30,10 +32,14 @@ module ActionView
|
||||
# form_tag('/upload', :multipart => true)
|
||||
# # => <form action="/upload" method="post" enctype="multipart/form-data">
|
||||
#
|
||||
# <% form_tag '/posts' do -%>
|
||||
# <% form_tag('/posts')do -%>
|
||||
# <div><%= submit_tag 'Save' %></div>
|
||||
# <% end -%>
|
||||
# # => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
|
||||
#
|
||||
# <% form_tag('/posts', :remote => true) %>
|
||||
# # => <form action="/posts" method="post" data-remote="true">
|
||||
#
|
||||
def form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)
|
||||
html_options = html_options_for_form(url_for_options, options, *parameters_for_url)
|
||||
if block_given?
|
||||
@@ -333,12 +339,13 @@ module ActionView
|
||||
# Creates a submit button with the text <tt>value</tt> as the caption.
|
||||
#
|
||||
# ==== Options
|
||||
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
|
||||
# prompt with the question specified. If the user accepts, the form is
|
||||
# processed normally, otherwise no action is taken.
|
||||
# * <tt>:confirm => 'question?'</tt> - If present the unobtrusive JavaScript
|
||||
# drivers will provide a prompt with the question specified. If the user accepts,
|
||||
# the form is processed normally, otherwise no action is taken.
|
||||
# * <tt>:disabled</tt> - If true, the user will not be able to use this input.
|
||||
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a disabled version
|
||||
# of the submit button when the form is submitted.
|
||||
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
|
||||
# disabled version of the submit button when the form is submitted. This feature is
|
||||
# provided by the unobtrusive JavaScript driver.
|
||||
# * Any other key creates standard HTML options for the tag.
|
||||
#
|
||||
# ==== Examples
|
||||
@@ -351,16 +358,22 @@ module ActionView
|
||||
# submit_tag "Save edits", :disabled => true
|
||||
# # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
|
||||
#
|
||||
#
|
||||
# submit_tag "Complete sale", :disable_with => "Please wait..."
|
||||
# # => <input name="commit" onclick="this.disabled=true;this.value='Please wait...';this.form.submit();"
|
||||
# # => <input name="commit" data-disable-with="Please wait..."
|
||||
# # type="submit" value="Complete sale" />
|
||||
#
|
||||
# submit_tag nil, :class => "form_submit"
|
||||
# # => <input class="form_submit" name="commit" type="submit" />
|
||||
#
|
||||
# submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button"
|
||||
# # => <input class="edit-button" onclick="this.disabled=true;this.value='Editing...';this.form.submit();"
|
||||
# # => <input class="edit-button" data-disable_with="Editing..."
|
||||
# # name="commit" type="submit" value="Edit" />
|
||||
#
|
||||
# submit_tag "Save", :confirm => "Are you sure?"
|
||||
# # => <input name='commit' type='submit' value='Save'
|
||||
# data-confirm="Are you sure?" />
|
||||
#
|
||||
def submit_tag(value = "Save changes", options = {})
|
||||
options.stringify_keys!
|
||||
|
||||
@@ -433,7 +446,7 @@ module ActionView
|
||||
concat(tag(:fieldset, options, true))
|
||||
concat(content_tag(:legend, legend)) unless legend.blank?
|
||||
concat(content)
|
||||
concat("</fieldset>".html_safe!)
|
||||
safe_concat("</fieldset>")
|
||||
end
|
||||
|
||||
private
|
||||
@@ -441,6 +454,7 @@ module ActionView
|
||||
returning options.stringify_keys do |html_options|
|
||||
html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
|
||||
html_options["action"] = url_for(url_for_options, *parameters_for_url)
|
||||
html_options["data-remote"] = true if html_options.delete("remote")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -460,14 +474,14 @@ module ActionView
|
||||
|
||||
def form_tag_html(html_options)
|
||||
extra_tags = extra_tags_for_form(html_options)
|
||||
(tag(:form, html_options, true) + extra_tags).html_safe!
|
||||
(tag(:form, html_options, true) + extra_tags).html_safe
|
||||
end
|
||||
|
||||
def form_tag_in_block(html_options, &block)
|
||||
content = capture(&block)
|
||||
concat(form_tag_html(html_options))
|
||||
concat(content)
|
||||
concat("</form>".html_safe!)
|
||||
safe_concat("</form>")
|
||||
end
|
||||
|
||||
def token_tag
|
||||
|
||||
@@ -92,7 +92,7 @@ module ActionView
|
||||
:precision => precision,
|
||||
:delimiter => delimiter,
|
||||
:separator => separator)
|
||||
).gsub(/%u/, unit).html_safe!
|
||||
).gsub(/%u/, unit).html_safe
|
||||
rescue
|
||||
number
|
||||
end
|
||||
|
||||
@@ -610,7 +610,7 @@ module ActionView
|
||||
# page.hide 'spinner'
|
||||
# end
|
||||
def update_page(&block)
|
||||
JavaScriptGenerator.new(@template, &block).to_s.html_safe!
|
||||
JavaScriptGenerator.new(@template, &block).to_s.html_safe
|
||||
end
|
||||
|
||||
# Works like update_page but wraps the generated JavaScript in a <script>
|
||||
|
||||
@@ -2,7 +2,7 @@ module ActionView #:nodoc:
|
||||
module Helpers #:nodoc:
|
||||
module RawOutputHelper
|
||||
def raw(stringish)
|
||||
stringish.to_s.html_safe!
|
||||
stringish.to_s.html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,11 +50,7 @@ module ActionView
|
||||
# confuse browsers.
|
||||
#
|
||||
def sanitize(html, options = {})
|
||||
returning self.class.white_list_sanitizer.sanitize(html, options) do |sanitized|
|
||||
if sanitized
|
||||
sanitized.html_safe!
|
||||
end
|
||||
end
|
||||
self.class.white_list_sanitizer.sanitize(html, options).try(:html_safe)
|
||||
end
|
||||
|
||||
# Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute.
|
||||
@@ -77,11 +73,7 @@ module ActionView
|
||||
# strip_tags("<div id='top-bar'>Welcome to my website!</div>")
|
||||
# # => Welcome to my website!
|
||||
def strip_tags(html)
|
||||
returning self.class.full_sanitizer.sanitize(html) do |sanitized|
|
||||
if sanitized
|
||||
sanitized.html_safe!
|
||||
end
|
||||
end
|
||||
self.class.full_sanitizer.sanitize(html).try(:html_safe)
|
||||
end
|
||||
|
||||
# Strips all link tags from +text+ leaving just the link text.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
require 'action_view/erb/util'
|
||||
require 'set'
|
||||
|
||||
module ActionView
|
||||
@@ -41,7 +40,7 @@ module ActionView
|
||||
# tag("img", { :src => "open & shut.png" }, false, false)
|
||||
# # => <img src="open & shut.png" />
|
||||
def tag(name, options = nil, open = false, escape = true)
|
||||
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe!
|
||||
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
|
||||
end
|
||||
|
||||
# Returns an HTML block tag of type +name+ surrounding the +content+. Add
|
||||
@@ -94,7 +93,7 @@ module ActionView
|
||||
# cdata_section(File.read("hello_world.txt"))
|
||||
# # => <![CDATA[<hello from a text file]]>
|
||||
def cdata_section(content)
|
||||
"<![CDATA[#{content}]]>".html_safe!
|
||||
"<![CDATA[#{content}]]>".html_safe
|
||||
end
|
||||
|
||||
# Returns an escaped version of +html+ without affecting existing escaped entities.
|
||||
@@ -128,7 +127,7 @@ module ActionView
|
||||
|
||||
def content_tag_string(name, content, options, escape = true)
|
||||
tag_options = tag_options(options, escape) if options
|
||||
"<#{name}#{tag_options}>#{content}</#{name}>".html_safe!
|
||||
"<#{name}#{tag_options}>#{content}</#{name}>".html_safe
|
||||
end
|
||||
|
||||
def tag_options(options, escape = true)
|
||||
@@ -143,7 +142,7 @@ module ActionView
|
||||
attrs << %(#{key}="#{final_value}")
|
||||
end
|
||||
end
|
||||
" #{attrs.sort * ' '}".html_safe! unless attrs.empty?
|
||||
" #{attrs.sort * ' '}".html_safe unless attrs.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,14 +24,14 @@ module ActionView
|
||||
# end
|
||||
# # will either display "Logged in!" or a login link
|
||||
# %>
|
||||
def concat(string, unused_binding = nil)
|
||||
if unused_binding
|
||||
ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.", caller)
|
||||
end
|
||||
|
||||
def concat(string)
|
||||
output_buffer << string
|
||||
end
|
||||
|
||||
def safe_concat(string)
|
||||
output_buffer.safe_concat(string)
|
||||
end
|
||||
|
||||
# Truncates a given +text+ after a given <tt>:length</tt> if +text+ is longer than <tt>:length</tt>
|
||||
# (defaults to 30). The last characters will be replaced with the <tt>:omission</tt> (defaults to "...")
|
||||
# for a total length not exceeding <tt>:length</tt>.
|
||||
|
||||
@@ -12,7 +12,7 @@ module ActionView
|
||||
# prepend the key with a period, nothing is converted.
|
||||
def translate(key, options = {})
|
||||
options[:raise] = true
|
||||
I18n.translate(scope_key_by_partial(key), options).html_safe!
|
||||
I18n.translate(scope_key_by_partial(key), options).html_safe
|
||||
rescue I18n::MissingTranslationData => e
|
||||
keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope])
|
||||
content_tag('span', keys.join(', '), :class => 'translation_missing')
|
||||
|
||||
@@ -98,7 +98,7 @@ module ActionView
|
||||
polymorphic_path(options)
|
||||
end
|
||||
|
||||
escape ? escape_once(url).html_safe! : url
|
||||
escape ? escape_once(url).html_safe : url
|
||||
end
|
||||
|
||||
# Creates a link tag of the given +name+ using a URL created by the set
|
||||
@@ -117,8 +117,8 @@ module ActionView
|
||||
# end
|
||||
#
|
||||
# ==== Options
|
||||
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
|
||||
# prompt with the question specified. If the user accepts, the link is
|
||||
# * <tt>:confirm => 'question?'</tt> - This will allow the unobtrusive JavaScript
|
||||
# driver to prompt with the question specified. If the user accepts, the link is
|
||||
# processed normally, otherwise no action is taken.
|
||||
# * <tt>:method => symbol of HTTP verb</tt> - This modifier will dynamically
|
||||
# create an HTML form and immediately submit the form for processing using
|
||||
@@ -195,23 +195,20 @@ module ActionView
|
||||
# link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")
|
||||
# # => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>
|
||||
#
|
||||
# The three options specific to +link_to+ (<tt>:confirm</tt> and <tt>:method</tt>) are used as follows:
|
||||
# The two options specific to +link_to+ (<tt>:confirm</tt> and <tt>:method</tt>) are used as follows:
|
||||
#
|
||||
# link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
|
||||
# # => <a href="http://www.rubyonrails.org/" onclick="return confirm('Are you sure?');">Visit Other Site</a>
|
||||
# # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?"">Visit Other Site</a>
|
||||
#
|
||||
# link_to("Destroy", "http://www.example.com", :method => :delete, :confirm => "Are you sure?")
|
||||
# # => <a href='http://www.example.com' rel="nofollow" data-method="delete" data-confirm="Are you sure?">Destroy</a>
|
||||
|
||||
#
|
||||
# link_to "Delete Image", @image, :confirm => "Are you sure?", :method => :delete
|
||||
# # => <a href="/images/9" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form');
|
||||
# f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
|
||||
# var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method');
|
||||
# m.setAttribute('value', 'delete');var s = document.createElement('input'); s.setAttribute('type', 'hidden');
|
||||
# s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'Q/ttlxPYZ6R77B+vZ1sBkhj21G2isO9dpE6UtOHBApg=');
|
||||
# f.appendChild(s)f.appendChild(m);f.submit(); };return false;">Delete Image</a>
|
||||
def link_to(*args, &block)
|
||||
if block_given?
|
||||
options = args.first || {}
|
||||
html_options = args.second
|
||||
concat(link_to(capture(&block), options, html_options).html_safe!)
|
||||
safe_concat(link_to(capture(&block), options, html_options))
|
||||
else
|
||||
name = args[0]
|
||||
options = args[1] || {}
|
||||
@@ -229,7 +226,7 @@ module ActionView
|
||||
end
|
||||
|
||||
href_attr = "href=\"#{url}\"" unless href
|
||||
"<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe!
|
||||
"<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -256,9 +253,11 @@ module ActionView
|
||||
# There are a few special +html_options+:
|
||||
# * <tt>:method</tt> - Specifies the anchor name to be appended to the path.
|
||||
# * <tt>:disabled</tt> - Specifies the anchor name to be appended to the path.
|
||||
# * <tt>:confirm</tt> - This will add a JavaScript confirm
|
||||
# * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
|
||||
# prompt with the question specified. If the user accepts, the link is
|
||||
# processed normally, otherwise no action is taken.
|
||||
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
|
||||
# submit behaviour. By default this behaviour is an ajax submit.
|
||||
#
|
||||
# ==== Examples
|
||||
# <%= button_to "New", :action => "new" %>
|
||||
@@ -266,15 +265,27 @@ module ActionView
|
||||
# # <div><input value="New" type="submit" /></div>
|
||||
# # </form>"
|
||||
#
|
||||
# button_to "Delete Image", { :action => "delete", :id => @image.id },
|
||||
# :confirm => "Are you sure?", :method => :delete
|
||||
#
|
||||
# <%= button_to "Delete Image", { :action => "delete", :id => @image.id },
|
||||
# :confirm => "Are you sure?", :method => :delete %>
|
||||
# # => "<form method="post" action="/images/delete/1" class="button-to">
|
||||
# # <div>
|
||||
# # <input type="hidden" name="_method" value="delete" />
|
||||
# # <input onclick="return confirm('Are you sure?');"
|
||||
# # value="Delete" type="submit" />
|
||||
# # <input data-confirm='Are you sure?' value="Delete" type="submit" />
|
||||
# # </div>
|
||||
# # </form>"
|
||||
#
|
||||
#
|
||||
# <%= button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
|
||||
# :method => "delete", :remote => true, :disable_with => 'loading...') %>
|
||||
# # => "<form class='button-to' method='post' action='http://www.example.com' data-remote='true'>
|
||||
# # <div>
|
||||
# # <input name='_method' value='delete' type='hidden' />
|
||||
# # <input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' />
|
||||
# # </div>
|
||||
# # </form>"
|
||||
# #
|
||||
|
||||
def button_to(name, options = {}, html_options = {})
|
||||
html_options = html_options.stringify_keys
|
||||
convert_boolean_attributes!(html_options, %w( disabled ))
|
||||
@@ -286,6 +297,8 @@ module ActionView
|
||||
|
||||
form_method = method.to_s == 'get' ? 'get' : 'post'
|
||||
|
||||
remote = html_options.delete('remote')
|
||||
|
||||
request_token_tag = ''
|
||||
if form_method == 'post' && protect_against_forgery?
|
||||
request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
|
||||
@@ -298,8 +311,8 @@ module ActionView
|
||||
|
||||
html_options.merge!("type" => "submit", "value" => name)
|
||||
|
||||
("<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button-to\"><div>" +
|
||||
method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe!
|
||||
("<form method=\"#{form_method}\" action=\"#{escape_once url}\" #{"data-remote=\"true\"" if remote} class=\"button-to\"><div>" +
|
||||
method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe
|
||||
end
|
||||
|
||||
|
||||
@@ -565,14 +578,8 @@ module ActionView
|
||||
|
||||
method, href = html_options.delete("method"), html_options['href']
|
||||
|
||||
if confirm && method
|
||||
add_confirm_to_attributes!(html_options, confirm)
|
||||
add_method_to_attributes!(html_options, method)
|
||||
elsif confirm
|
||||
add_confirm_to_attributes!(html_options, confirm)
|
||||
elsif method
|
||||
add_method_to_attributes!(html_options, method)
|
||||
end
|
||||
add_confirm_to_attributes!(html_options, confirm) if confirm
|
||||
add_method_to_attributes!(html_options, method) if method
|
||||
|
||||
html_options["data-url"] = options[:url] if options.is_a?(Hash) && options[:url]
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ module ActionView
|
||||
end
|
||||
|
||||
result = @template ? collection_with_template : collection_without_template
|
||||
result.join(spacer).html_safe!
|
||||
result.join(spacer).html_safe
|
||||
end
|
||||
|
||||
def collection_with_template(template = @template)
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
module ActionView #:nodoc:
|
||||
class SafeBuffer < String
|
||||
def <<(value)
|
||||
if value.html_safe?
|
||||
super(value)
|
||||
else
|
||||
super(ERB::Util.h(value))
|
||||
end
|
||||
end
|
||||
|
||||
def concat(value)
|
||||
self << value
|
||||
end
|
||||
|
||||
def html_safe?
|
||||
true
|
||||
end
|
||||
|
||||
def html_safe!
|
||||
self
|
||||
end
|
||||
|
||||
def to_s
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
require "active_support/core_ext/class/inheritable_attributes"
|
||||
require "action_dispatch/http/mime_type"
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
# Legacy TemplateHandler stub
|
||||
module ActionView
|
||||
@@ -23,7 +23,7 @@ module ActionView
|
||||
end
|
||||
|
||||
class Template::Handler
|
||||
extlib_inheritable_accessor :default_format
|
||||
class_attribute :default_format
|
||||
self.default_format = Mime::HTML
|
||||
|
||||
def self.call(template)
|
||||
|
||||
@@ -6,7 +6,7 @@ module ActionView
|
||||
module Template::Handlers
|
||||
class Erubis < ::Erubis::Eruby
|
||||
def add_preamble(src)
|
||||
src << "@output_buffer = ActionView::SafeBuffer.new;"
|
||||
src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
|
||||
end
|
||||
|
||||
def add_text(src, text)
|
||||
@@ -15,7 +15,11 @@ module ActionView
|
||||
end
|
||||
|
||||
def add_expr_literal(src, code)
|
||||
src << '@output_buffer << ((' << code << ').to_s);'
|
||||
if code =~ /\s*raw\s+(.*)/
|
||||
src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
|
||||
else
|
||||
src << '@output_buffer << ((' << code << ').to_s);'
|
||||
end
|
||||
end
|
||||
|
||||
def add_expr_escaped(src, code)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require "pathname"
|
||||
require "active_support/core_ext/class"
|
||||
require "active_support/core_ext/array/wrap"
|
||||
require "action_view/template"
|
||||
|
||||
module ActionView
|
||||
@@ -11,7 +12,7 @@ module ActionView
|
||||
|
||||
def self.register_detail(name, options = {})
|
||||
registered_details[name] = lambda do |val|
|
||||
val ||= yield
|
||||
val = Array.wrap(val || yield)
|
||||
val |= [nil] unless options[:allow_nil] == false
|
||||
val
|
||||
end
|
||||
@@ -141,8 +142,7 @@ module ActionView
|
||||
end
|
||||
end
|
||||
|
||||
# OMG HAX
|
||||
# TODO: remove hax
|
||||
# TODO: remove hack
|
||||
class FileSystemResolverWithFallback < Resolver
|
||||
def initialize(path, options = {})
|
||||
super(options)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'action_controller/test_case'
|
||||
|
||||
module ActionView
|
||||
class Base
|
||||
alias_method :initialize_without_template_tracking, :initialize
|
||||
@@ -51,7 +53,7 @@ module ActionView
|
||||
setup :setup_with_controller
|
||||
def setup_with_controller
|
||||
@controller = TestController.new
|
||||
@output_buffer = ActionView::SafeBuffer.new
|
||||
@output_buffer = ActiveSupport::SafeBuffer.new
|
||||
@rendered = ''
|
||||
|
||||
self.class.send(:include_helper_modules!)
|
||||
|
||||
@@ -13,7 +13,7 @@ module AbstractControllerTests
|
||||
"layouts/hello_override.erb" => "With Override <%= yield %>",
|
||||
"layouts/abstract_controller_tests/layouts/with_string_implied_child.erb" =>
|
||||
"With Implied <%= yield %>",
|
||||
"layouts/omg.erb" => "OMGHI2U <%= yield %>",
|
||||
"layouts/overwrite.erb" => "Overwrite <%= yield %>",
|
||||
"layouts/with_false_layout.erb" => "False Layout <%= yield %>"
|
||||
)]
|
||||
end
|
||||
@@ -42,7 +42,7 @@ module AbstractControllerTests
|
||||
end
|
||||
|
||||
def overwrite_string
|
||||
render :_template => ActionView::Template::Text.new("Hello string!"), :layout => "omg"
|
||||
render :_template => ActionView::Template::Text.new("Hello string!"), :layout => "overwrite"
|
||||
end
|
||||
|
||||
def overwrite_skip
|
||||
@@ -68,7 +68,7 @@ module AbstractControllerTests
|
||||
end
|
||||
|
||||
class WithProc < Base
|
||||
layout proc { |c| "omg" }
|
||||
layout proc { |c| "overwrite" }
|
||||
|
||||
def index
|
||||
render :_template => ActionView::Template::Text.new("Hello proc!")
|
||||
@@ -83,7 +83,7 @@ module AbstractControllerTests
|
||||
end
|
||||
private
|
||||
def hello
|
||||
"omg"
|
||||
"overwrite"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -122,7 +122,7 @@ module AbstractControllerTests
|
||||
end
|
||||
|
||||
class WithSymbolAndNoMethod < Base
|
||||
layout :omg_no_method
|
||||
layout :no_method
|
||||
|
||||
def index
|
||||
render :_template => ActionView::Template::Text.new("Hello boom!")
|
||||
@@ -175,7 +175,7 @@ module AbstractControllerTests
|
||||
test "when layout is overwriten by string in render, render new layout" do
|
||||
controller = WithString.new
|
||||
controller.process(:overwrite_string)
|
||||
assert_equal "OMGHI2U Hello string!", controller.response_body
|
||||
assert_equal "Overwrite Hello string!", controller.response_body
|
||||
end
|
||||
|
||||
test "when layout is overwriten by false in render, render no layout" do
|
||||
@@ -209,13 +209,13 @@ module AbstractControllerTests
|
||||
test "when layout is specified as a proc, call it and use the layout returned" do
|
||||
controller = WithProc.new
|
||||
controller.process(:index)
|
||||
assert_equal "OMGHI2U Hello proc!", controller.response_body
|
||||
assert_equal "Overwrite Hello proc!", controller.response_body
|
||||
end
|
||||
|
||||
test "when layout is specified as a symbol, call the requested method and use the layout returned" do
|
||||
controller = WithSymbol.new
|
||||
controller.process(:index)
|
||||
assert_equal "OMGHI2U Hello symbol!", controller.response_body
|
||||
assert_equal "Overwrite Hello symbol!", controller.response_body
|
||||
end
|
||||
|
||||
test "when layout is specified as a symbol and the method returns nil, don't use a layout" do
|
||||
@@ -266,7 +266,7 @@ module AbstractControllerTests
|
||||
test "raises an exception when specifying layout true" do
|
||||
assert_raises ArgumentError do
|
||||
Object.class_eval do
|
||||
class ::BadOmgFailLolLayout < AbstractControllerTests::Layouts::Base
|
||||
class ::BadFailLayout < AbstractControllerTests::Layouts::Base
|
||||
layout true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
begin
|
||||
require File.expand_path('../../../vendor/gems/environment', __FILE__)
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
lib = File.expand_path('../../lib', __FILE__)
|
||||
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
||||
require File.expand_path('../../../load_paths', __FILE__)
|
||||
|
||||
$:.unshift(File.dirname(__FILE__) + '/lib')
|
||||
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
|
||||
@@ -20,9 +14,6 @@ require 'action_view/base'
|
||||
require 'action_dispatch'
|
||||
require 'fixture_template'
|
||||
require 'active_support/dependencies'
|
||||
|
||||
activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
|
||||
$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
|
||||
require 'active_model'
|
||||
|
||||
begin
|
||||
|
||||
@@ -611,7 +611,7 @@ class FragmentCachingTest < ActionController::TestCase
|
||||
@store.write('views/expensive', 'fragment content')
|
||||
fragment_computed = false
|
||||
|
||||
buffer = 'generated till now -> '
|
||||
buffer = 'generated till now -> '.html_safe
|
||||
@controller.fragment_for(buffer, 'expensive') { fragment_computed = true }
|
||||
|
||||
assert fragment_computed
|
||||
@@ -622,7 +622,7 @@ class FragmentCachingTest < ActionController::TestCase
|
||||
@store.write('views/expensive', 'fragment content')
|
||||
fragment_computed = false
|
||||
|
||||
buffer = 'generated till now -> '
|
||||
buffer = 'generated till now -> '.html_safe
|
||||
@controller.fragment_for(buffer, 'expensive') { fragment_computed = true }
|
||||
|
||||
assert !fragment_computed
|
||||
|
||||
@@ -435,7 +435,7 @@ class FilterTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
def non_yielding_filter
|
||||
@filters << "zomg it didn't yield"
|
||||
@filters << "it didn't yield"
|
||||
@filter_return_value
|
||||
end
|
||||
|
||||
@@ -465,14 +465,14 @@ class FilterTest < ActionController::TestCase
|
||||
controller = NonYieldingAroundFilterController.new
|
||||
controller.instance_variable_set "@filter_return_value", false
|
||||
test_process(controller, "index")
|
||||
assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
|
||||
assert_equal ["filter_one", "it didn't yield"], controller.assigns['filters']
|
||||
end
|
||||
|
||||
def test_after_filters_are_not_run_if_around_filter_does_not_yield
|
||||
controller = NonYieldingAroundFilterController.new
|
||||
controller.instance_variable_set "@filter_return_value", true
|
||||
test_process(controller, "index")
|
||||
assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
|
||||
assert_equal ["filter_one", "it didn't yield"], controller.assigns['filters']
|
||||
end
|
||||
|
||||
def test_added_filter_to_inheritance_graph
|
||||
|
||||
@@ -119,9 +119,9 @@ module RenderActionWithApplicationLayout
|
||||
# Set the view path to an application view structure with layouts
|
||||
self.view_paths = self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!",
|
||||
"render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Omg'",
|
||||
"layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI",
|
||||
"layouts/greetings.html.erb" => "Greetings <%= yield %> Bai",
|
||||
"render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Hello'",
|
||||
"layouts/application.html.erb" => "Hi <%= yield %> OK, Bye",
|
||||
"layouts/greetings.html.erb" => "Greetings <%= yield %> Bye",
|
||||
"layouts/builder.html.builder" => "xml.html do\n xml << yield\nend"
|
||||
)]
|
||||
|
||||
@@ -156,14 +156,14 @@ module RenderActionWithApplicationLayout
|
||||
test "rendering implicit application.html.erb as layout" do
|
||||
get "/render_action_with_application_layout/basic/hello_world"
|
||||
|
||||
assert_body "OHAI Hello World! KTHXBAI"
|
||||
assert_body "Hi Hello World! OK, Bye"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
test "rendering with layout => true" do
|
||||
get "/render_action_with_application_layout/basic/hello_world_with_layout"
|
||||
|
||||
assert_body "OHAI Hello World! KTHXBAI"
|
||||
assert_body "Hi Hello World! OK, Bye"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
@@ -184,7 +184,7 @@ module RenderActionWithApplicationLayout
|
||||
test "rendering with layout => 'greetings'" do
|
||||
get "/render_action_with_application_layout/basic/hello_world_with_custom_layout"
|
||||
|
||||
assert_body "Greetings Hello World! Bai"
|
||||
assert_body "Greetings Hello World! Bye"
|
||||
assert_status 200
|
||||
end
|
||||
end
|
||||
@@ -194,7 +194,7 @@ module RenderActionWithApplicationLayout
|
||||
|
||||
test "builder works with layouts" do
|
||||
get :with_builder_and_layout
|
||||
assert_response "<html>\n<p>Omg</p>\n</html>\n"
|
||||
assert_response "<html>\n<p>Hello</p>\n</html>\n"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -204,7 +204,7 @@ module RenderActionWithControllerLayout
|
||||
class BasicController < ActionController::Base
|
||||
self.view_paths = self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!",
|
||||
"layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI"
|
||||
"layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> Bye"
|
||||
)]
|
||||
|
||||
def hello_world
|
||||
@@ -234,14 +234,14 @@ module RenderActionWithControllerLayout
|
||||
test "render hello_world and implicitly use <controller_path>.html.erb as a layout." do
|
||||
get "/render_action_with_controller_layout/basic/hello_world"
|
||||
|
||||
assert_body "With Controller Layout! Hello World! KTHXBAI"
|
||||
assert_body "With Controller Layout! Hello World! Bye"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
test "rendering with layout => true" do
|
||||
get "/render_action_with_controller_layout/basic/hello_world_with_layout"
|
||||
|
||||
assert_body "With Controller Layout! Hello World! KTHXBAI"
|
||||
assert_body "With Controller Layout! Hello World! Bye"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
@@ -265,8 +265,8 @@ module RenderActionWithBothLayouts
|
||||
class BasicController < ActionController::Base
|
||||
self.view_paths = [ActionView::FixtureResolver.new({
|
||||
"render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!",
|
||||
"layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI",
|
||||
"layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI"
|
||||
"layouts/application.html.erb" => "Oh Hi <%= yield %> Bye",
|
||||
"layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> Bye"
|
||||
})]
|
||||
|
||||
def hello_world
|
||||
@@ -292,14 +292,14 @@ module RenderActionWithBothLayouts
|
||||
test "rendering implicitly use <controller_path>.html.erb over application.html.erb as a layout" do
|
||||
get "/render_action_with_both_layouts/basic/hello_world"
|
||||
|
||||
assert_body "With Controller Layout! Hello World! KTHXBAI"
|
||||
assert_body "With Controller Layout! Hello World! Bye"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
test "rendering with layout => true" do
|
||||
get "/render_action_with_both_layouts/basic/hello_world_with_layout"
|
||||
|
||||
assert_body "With Controller Layout! Hello World! KTHXBAI"
|
||||
assert_body "With Controller Layout! Hello World! Bye"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ require 'abstract_unit'
|
||||
module ControllerLayouts
|
||||
class ImplicitController < ::ApplicationController
|
||||
self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI",
|
||||
"layouts/application.html.erb" => "Main <%= yield %> Layout",
|
||||
"layouts/override.html.erb" => "Override! <%= yield %>",
|
||||
"basic.html.erb" => "Hello world!",
|
||||
"controller_layouts/implicit/layout_false.html.erb" => "hai(layout_false.html.erb)"
|
||||
"controller_layouts/implicit/layout_false.html.erb" => "hi(layout_false.html.erb)"
|
||||
)]
|
||||
|
||||
def index
|
||||
@@ -27,7 +27,7 @@ module ControllerLayouts
|
||||
|
||||
class ImplicitNameController < ::ApplicationController
|
||||
self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI",
|
||||
"layouts/controller_layouts/implicit_name.html.erb" => "Implicit <%= yield %> Layout",
|
||||
"basic.html.erb" => "Hello world!"
|
||||
)]
|
||||
|
||||
@@ -40,14 +40,14 @@ module ControllerLayouts
|
||||
test "rendering a normal template, but using the implicit layout" do
|
||||
get "/controller_layouts/implicit/index"
|
||||
|
||||
assert_body "OMG Hello world! KTHXBAI"
|
||||
assert_body "Main Hello world! Layout"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
test "rendering a normal template, but using an implicit NAMED layout" do
|
||||
get "/controller_layouts/implicit_name/index"
|
||||
|
||||
assert_body "OMGIMPLICIT Hello world! KTHXBAI"
|
||||
assert_body "Implicit Hello world! Layout"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
@@ -63,15 +63,15 @@ module ControllerLayouts
|
||||
|
||||
test "rendering with :layout => false leaves out the implicit layout" do
|
||||
get :layout_false
|
||||
assert_response "hai(layout_false.html.erb)"
|
||||
assert_response "hi(layout_false.html.erb)"
|
||||
end
|
||||
end
|
||||
|
||||
class MismatchFormatController < ::ApplicationController
|
||||
self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"layouts/application.html.erb" => "<html><%= yield %></html>",
|
||||
"controller_layouts/mismatch_format/index.js.rjs" => "page[:test].omg",
|
||||
"controller_layouts/mismatch_format/implicit.rjs" => "page[:test].omg"
|
||||
"controller_layouts/mismatch_format/index.js.rjs" => "page[:test].ext",
|
||||
"controller_layouts/mismatch_format/implicit.rjs" => "page[:test].ext"
|
||||
)]
|
||||
|
||||
def explicit
|
||||
@@ -84,12 +84,12 @@ module ControllerLayouts
|
||||
|
||||
test "if JS is selected, an HTML template is not also selected" do
|
||||
get :index, "format" => "js"
|
||||
assert_response "$(\"test\").omg();"
|
||||
assert_response "$(\"test\").ext();"
|
||||
end
|
||||
|
||||
test "if JS is implicitly selected, an HTML template is not also selected" do
|
||||
get :implicit
|
||||
assert_response "$(\"test\").omg();"
|
||||
assert_response "$(\"test\").ext();"
|
||||
end
|
||||
|
||||
test "if an HTML template is explicitly provides for a JS template, an error is raised" do
|
||||
|
||||
@@ -5,7 +5,7 @@ module RenderPartial
|
||||
class BasicController < ActionController::Base
|
||||
|
||||
self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"render_partial/basic/_basic.html.erb" => "OMG!",
|
||||
"render_partial/basic/_basic.html.erb" => "BasicPartial!",
|
||||
"render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>"
|
||||
)]
|
||||
|
||||
@@ -20,7 +20,7 @@ module RenderPartial
|
||||
|
||||
test "rendering a partial in ActionView doesn't pull the ivars again from the controller" do
|
||||
get :changing
|
||||
assert_response("goodbyeOMG!goodbye")
|
||||
assert_response("goodbyeBasicPartial!goodbye")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2,18 +2,19 @@ require 'abstract_unit'
|
||||
|
||||
module RenderTemplate
|
||||
class WithoutLayoutController < ActionController::Base
|
||||
|
||||
|
||||
self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"test/basic.html.erb" => "Hello from basic.html.erb",
|
||||
"shared.html.erb" => "Elastica",
|
||||
"locals.html.erb" => "The secret is <%= secret %>",
|
||||
"xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend"
|
||||
"xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend",
|
||||
"with_raw.html.erb" => "Hello <%=raw '<strong>this is raw</strong>' %>"
|
||||
)]
|
||||
|
||||
|
||||
def index
|
||||
render :template => "test/basic"
|
||||
end
|
||||
|
||||
|
||||
def index_without_key
|
||||
render "test/basic"
|
||||
end
|
||||
@@ -25,59 +26,70 @@ module RenderTemplate
|
||||
def in_top_directory_with_slash
|
||||
render :template => '/shared'
|
||||
end
|
||||
|
||||
|
||||
def in_top_directory_with_slash_without_key
|
||||
render '/shared'
|
||||
end
|
||||
|
||||
|
||||
def with_locals
|
||||
render :template => "locals", :locals => { :secret => 'area51' }
|
||||
end
|
||||
|
||||
|
||||
def builder_template
|
||||
render :template => "xml_template"
|
||||
end
|
||||
|
||||
def with_raw
|
||||
render :template => "with_raw"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class TestWithoutLayout < Rack::TestCase
|
||||
testing RenderTemplate::WithoutLayoutController
|
||||
|
||||
|
||||
test "rendering a normal template with full path without layout" do
|
||||
get :index
|
||||
assert_response "Hello from basic.html.erb"
|
||||
end
|
||||
|
||||
|
||||
test "rendering a normal template with full path without layout without key" do
|
||||
get :index_without_key
|
||||
assert_response "Hello from basic.html.erb"
|
||||
end
|
||||
|
||||
|
||||
test "rendering a template not in a subdirectory" do
|
||||
get :in_top_directory
|
||||
assert_response "Elastica"
|
||||
end
|
||||
|
||||
|
||||
test "rendering a template not in a subdirectory with a leading slash" do
|
||||
get :in_top_directory_with_slash
|
||||
assert_response "Elastica"
|
||||
end
|
||||
|
||||
|
||||
test "rendering a template not in a subdirectory with a leading slash without key" do
|
||||
get :in_top_directory_with_slash_without_key
|
||||
assert_response "Elastica"
|
||||
end
|
||||
|
||||
|
||||
test "rendering a template with local variables" do
|
||||
get :with_locals
|
||||
assert_response "The secret is area51"
|
||||
end
|
||||
|
||||
|
||||
test "rendering a builder template" do
|
||||
get :builder_template, "format" => "xml"
|
||||
assert_response "<html>\n <p>Hello</p>\n</html>\n"
|
||||
end
|
||||
|
||||
test "rendering a template with <%=raw stuff %>" do
|
||||
get :with_raw
|
||||
|
||||
assert_body "Hello <strong>this is raw</strong>"
|
||||
assert_status 200
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class WithLayoutController < ::ApplicationController
|
||||
self.view_paths = [ActionView::FixtureResolver.new(
|
||||
"test/basic.html.erb" => "Hello from basic.html.erb",
|
||||
@@ -85,28 +97,28 @@ module RenderTemplate
|
||||
"layouts/application.html.erb" => "<%= yield %>, I'm here!",
|
||||
"layouts/greetings.html.erb" => "<%= yield %>, I wish thee well."
|
||||
)]
|
||||
|
||||
|
||||
def index
|
||||
render :template => "test/basic"
|
||||
end
|
||||
|
||||
|
||||
def with_layout
|
||||
render :template => "test/basic", :layout => true
|
||||
end
|
||||
|
||||
|
||||
def with_layout_false
|
||||
render :template => "test/basic", :layout => false
|
||||
end
|
||||
|
||||
|
||||
def with_layout_nil
|
||||
render :template => "test/basic", :layout => nil
|
||||
end
|
||||
|
||||
|
||||
def with_custom_layout
|
||||
render :template => "test/basic", :layout => "greetings"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class TestWithLayout < Rack::TestCase
|
||||
describe "Rendering with :template using implicit or explicit layout"
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class OutputEscapingTest < ActiveSupport::TestCase
|
||||
test "escapeHTML shouldn't touch explicitly safe strings" do
|
||||
# TODO this seems easier to compose and reason about, but
|
||||
# this should be verified
|
||||
assert_equal "<", ERB::Util.h("<".html_safe!)
|
||||
assert_equal "<", ERB::Util.h("<".html_safe)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ module Another
|
||||
end
|
||||
|
||||
def data_sender
|
||||
send_data "cool data", :filename => "omg.txt"
|
||||
send_data "cool data", :filename => "file.txt"
|
||||
end
|
||||
|
||||
def xfile_sender
|
||||
@@ -121,7 +121,7 @@ class ACSubscriberTest < ActionController::TestCase
|
||||
wait
|
||||
|
||||
assert_equal 3, logs.size
|
||||
assert_match /Sent data omg\.txt/, logs[1]
|
||||
assert_match /Sent data file\.txt/, logs[1]
|
||||
end
|
||||
|
||||
def test_send_file
|
||||
|
||||
@@ -142,9 +142,9 @@ class ViewLoadPathsTest < ActionController::TestCase
|
||||
assert_paths A, "a/path"
|
||||
assert_paths A, *B.view_paths
|
||||
assert_paths C, *original_load_paths
|
||||
|
||||
|
||||
C.view_paths = []
|
||||
assert_nothing_raised { C.view_paths << 'c/path' }
|
||||
assert_nothing_raised { C.append_view_path 'c/path' }
|
||||
assert_paths C, "c/path"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ class MimeTypeTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
# Accept header send with user HTTP_USER_AGENT: Sunrise/0.42j (Windows XP)
|
||||
test "parse crappy broken acceptlines" do
|
||||
test "parse broken acceptlines" do
|
||||
accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/*,,*/*;q=0.5"
|
||||
expect = [Mime::HTML, Mime::XML, "image/*", Mime::TEXT, Mime::ALL]
|
||||
assert_equal expect, Mime::Type.parse(accept).collect { |c| c.to_s }
|
||||
@@ -31,7 +31,7 @@ class MimeTypeTest < ActiveSupport::TestCase
|
||||
|
||||
# Accept header send with user HTTP_USER_AGENT: Mozilla/4.0
|
||||
# (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.1)
|
||||
test "parse crappy broken acceptlines2" do
|
||||
test "parse other broken acceptlines" do
|
||||
accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, , pronto/1.00.00, sslvpn/1.00.00.00, */*"
|
||||
expect = ['image/gif', 'image/x-xbitmap', 'image/jpeg','image/pjpeg', 'application/x-shockwave-flash', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/msword', 'pronto/1.00.00', 'sslvpn/1.00.00.00', Mime::ALL ]
|
||||
assert_equal expect, Mime::Type.parse(accept).collect { |c| c.to_s }
|
||||
|
||||
@@ -22,7 +22,7 @@ class ErbUtilTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_html_escape_passes_html_escpe_unmodified
|
||||
escaped = h("<p>".html_safe!)
|
||||
escaped = h("<p>".html_safe)
|
||||
assert_equal "<p>", escaped
|
||||
assert escaped.html_safe?
|
||||
end
|
||||
|
||||
@@ -451,6 +451,25 @@ class FormHelperTest < ActionView::TestCase
|
||||
assert_dom_equal expected, output_buffer
|
||||
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)
|
||||
end
|
||||
|
||||
expected =
|
||||
"<form action='http://www.example.com' id='create-post' method='post' data-remote='true'>" +
|
||||
"<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
|
||||
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
|
||||
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||
"<input name='post[secret]' type='hidden' value='0' />" +
|
||||
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_without_object
|
||||
form_for(:post, :html => { :id => 'create-post' }) do |f|
|
||||
concat f.text_field(:title)
|
||||
@@ -1151,7 +1170,7 @@ class FormHelperTest < ActionView::TestCase
|
||||
(field_helpers - %w(hidden_field)).each do |selector|
|
||||
src = <<-END_SRC
|
||||
def #{selector}(field, *args, &proc)
|
||||
("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe!
|
||||
("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe
|
||||
end
|
||||
END_SRC
|
||||
class_eval src, __FILE__, __LINE__
|
||||
|
||||
@@ -53,6 +53,12 @@ class FormTagHelperTest < ActionView::TestCase
|
||||
assert_dom_equal expected, actual
|
||||
end
|
||||
|
||||
def test_form_tag_with_remote
|
||||
actual = form_tag({}, :remote => true)
|
||||
expected = %(<form action="http://www.example.com" method="post" data-remote="true">)
|
||||
assert_dom_equal expected, actual
|
||||
end
|
||||
|
||||
def test_form_tag_with_block_in_erb
|
||||
__in_erb_template = ''
|
||||
form_tag("http://example.com") { concat "Hello world!" }
|
||||
@@ -329,19 +335,19 @@ class FormTagHelperTest < ActionView::TestCase
|
||||
expected = %(<fieldset><legend>Your details</legend>Hello world!</fieldset>)
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
||||
self.output_buffer = ''
|
||||
self.output_buffer = ''.html_safe
|
||||
field_set_tag { concat "Hello world!" }
|
||||
|
||||
expected = %(<fieldset>Hello world!</fieldset>)
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
||||
self.output_buffer = ''
|
||||
self.output_buffer = ''.html_safe
|
||||
field_set_tag('') { concat "Hello world!" }
|
||||
|
||||
expected = %(<fieldset>Hello world!</fieldset>)
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
||||
self.output_buffer = ''
|
||||
self.output_buffer = ''.html_safe
|
||||
field_set_tag('', :class => 'format') { concat "Hello world!" }
|
||||
|
||||
expected = %(<fieldset class="format">Hello world!</fieldset>)
|
||||
|
||||
@@ -48,7 +48,7 @@ class SanitizerTest < ActionController::TestCase
|
||||
assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f"
|
||||
end
|
||||
|
||||
# fucked
|
||||
# TODO: Clean up
|
||||
def test_sanitize_js_handlers
|
||||
raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
|
||||
assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>}
|
||||
@@ -193,7 +193,7 @@ class SanitizerTest < ActionController::TestCase
|
||||
assert_sanitized img_hack, "<img>"
|
||||
end
|
||||
|
||||
# fucked
|
||||
# TODO: Clean up
|
||||
def test_should_sanitize_attributes
|
||||
assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'><script>alert()</script>">blah</span>)
|
||||
end
|
||||
|
||||
@@ -33,7 +33,7 @@ class AVSubscriberTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
def test_render_text_template
|
||||
@view.render(:text => "OMG")
|
||||
@view.render(:text => "TEXT")
|
||||
wait
|
||||
|
||||
assert_equal 1, @logger.logged(:info).size
|
||||
@@ -41,7 +41,7 @@ class AVSubscriberTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
def test_render_inline_template
|
||||
@view.render(:inline => "<%= 'OMG' %>")
|
||||
@view.render(:inline => "<%= 'TEXT' %>")
|
||||
wait
|
||||
|
||||
assert_equal 1, @logger.logged(:info).size
|
||||
|
||||
@@ -160,7 +160,7 @@ module ActionView
|
||||
class AssertionsTest < ActionView::TestCase
|
||||
def render_from_helper
|
||||
form_tag('/foo') do
|
||||
concat render(:text => '<ul><li>foo</li></ul>').html_safe!
|
||||
safe_concat render(:text => '<ul><li>foo</li></ul>')
|
||||
end
|
||||
end
|
||||
helper_method :render_from_helper
|
||||
|
||||
@@ -81,6 +81,13 @@ class UrlHelperTest < ActionView::TestCase
|
||||
)
|
||||
end
|
||||
|
||||
def test_button_to_with_remote_and_javascript_confirm
|
||||
assert_dom_equal(
|
||||
"<form method=\"post\" action=\"http://www.example.com\" class=\"button-to\" data-remote=\"true\"><div><input data-confirm=\"Are you sure?\" type=\"submit\" value=\"Hello\" /></div></form>",
|
||||
button_to("Hello", "http://www.example.com", :remote => true, :confirm => "Are you sure?")
|
||||
)
|
||||
end
|
||||
|
||||
def test_button_to_enabled_disabled
|
||||
assert_dom_equal(
|
||||
"<form method=\"post\" action=\"http://www.example.com\" class=\"button-to\"><div><input type=\"submit\" value=\"Hello\" /></div></form>",
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
begin
|
||||
require File.expand_path('../../../../vendor/gems/environment', __FILE__)
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
lib = File.expand_path('../../../lib', __FILE__)
|
||||
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
||||
require File.expand_path('../../../../load_paths', __FILE__)
|
||||
|
||||
require 'config'
|
||||
require 'active_model'
|
||||
|
||||
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
||||
|
||||
s.add_dependency('activesupport', '= 3.0.pre')
|
||||
s.add_dependency('activemodel', '= 3.0.pre')
|
||||
s.add_dependency('arel', '= 0.2.pre')
|
||||
s.add_dependency('arel', '~> 0.2.0')
|
||||
|
||||
s.require_path = 'lib'
|
||||
s.autorequire = 'active_record'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActiveRecord
|
||||
# Observer classes respond to lifecycle callbacks to implement trigger-like
|
||||
# behavior outside the original class. This is a great way to reduce the
|
||||
@@ -85,7 +87,8 @@ module ActiveRecord
|
||||
# singletons and that call instantiates and registers them.
|
||||
#
|
||||
class Observer < ActiveModel::Observer
|
||||
extlib_inheritable_accessor(:observed_methods){ [] }
|
||||
class_attribute :observed_methods
|
||||
self.observed_methods = []
|
||||
|
||||
def initialize
|
||||
super
|
||||
@@ -93,7 +96,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def self.method_added(method)
|
||||
observed_methods << method if ActiveRecord::Callbacks::CALLBACKS.include?(method.to_sym)
|
||||
self.observed_methods += [method] if ActiveRecord::Callbacks::CALLBACKS.include?(method.to_sym)
|
||||
end
|
||||
|
||||
protected
|
||||
@@ -106,7 +109,7 @@ module ActiveRecord
|
||||
|
||||
# Check if a notifier callback was already added to the given class. If
|
||||
# it was not, add it.
|
||||
self.observed_methods.each do |method|
|
||||
self.class.observed_methods.each do |method|
|
||||
callback = :"_notify_observers_for_#{method}"
|
||||
if (klass.instance_methods & [callback, callback.to_s]).empty?
|
||||
klass.class_eval "def #{callback}; notify_observers(:#{method}); end"
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
begin
|
||||
require File.expand_path('../../../../vendor/gems/environment', __FILE__)
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
lib = File.expand_path('../../../lib', __FILE__)
|
||||
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
||||
require File.expand_path('../../../../load_paths', __FILE__)
|
||||
|
||||
require 'config'
|
||||
|
||||
require 'rubygems'
|
||||
require 'test/unit'
|
||||
require 'stringio'
|
||||
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
begin
|
||||
require File.expand_path('../../../vendor/gems/environment', __FILE__)
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
lib = File.expand_path('../../lib', __FILE__)
|
||||
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
||||
require File.expand_path('../../../load_paths', __FILE__)
|
||||
|
||||
require 'rubygems'
|
||||
require 'test/unit'
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
*Rails 3.0 (pending)*
|
||||
|
||||
* Introduce class_attribute to declare inheritable class attributes. Writing an attribute on a subclass behaves just like overriding the superclass reader method. Unifies and replaces most usage of cattr_accessor, class_inheritable_attribute, superclass_delegating_attribute, and extlib_inheritable_attribute. [Jeremy Kemper, Yehuda Katz]
|
||||
|
||||
* Time#- with a DateTime argument behaves the same as with a Time argument, i.e. returns the difference between self and arg as a Float #3476 [Geoff Buesing]
|
||||
|
||||
* YAML serialization for OrderedHash. #3608 [Gregor Schmidt]
|
||||
|
||||
@@ -67,5 +67,6 @@ module ActiveSupport
|
||||
autoload :XmlMini
|
||||
end
|
||||
|
||||
autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
|
||||
autoload :TestCase
|
||||
end
|
||||
|
||||
36
activesupport/lib/active_support/core_ext/class/attribute.rb
Normal file
36
activesupport/lib/active_support/core_ext/class/attribute.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
require 'active_support/core_ext/object/metaclass'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
class Class
|
||||
# Declare a class-level attribute whose value is inheritable and
|
||||
# overwritable by subclasses:
|
||||
#
|
||||
# class Base
|
||||
# class_attribute :setting
|
||||
# end
|
||||
#
|
||||
# class Subclass < Base
|
||||
# end
|
||||
#
|
||||
# Base.setting = true
|
||||
# Subclass.setting # => true
|
||||
# Subclass.setting = false
|
||||
# Subclass.setting # => false
|
||||
# Base.setting # => true
|
||||
#
|
||||
# This matches normal Ruby method inheritance: think of writing an attribute
|
||||
# on a subclass as overriding the reader method.
|
||||
#
|
||||
# For convenience, a query method is defined as well:
|
||||
#
|
||||
# Subclass.setting? # => false
|
||||
def class_attribute(*attrs)
|
||||
attrs.each do |attr|
|
||||
metaclass.send(:define_method, attr) { }
|
||||
metaclass.send(:define_method, "#{attr}?") { !!send(attr) }
|
||||
metaclass.send(:define_method, "#{attr}=") do |value|
|
||||
metaclass.send(:define_method, attr) { value }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,53 @@
|
||||
require "erb"
|
||||
|
||||
class ERB
|
||||
module Util
|
||||
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
||||
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
||||
|
||||
# A utility method for escaping HTML tag characters.
|
||||
# This method is also aliased as <tt>h</tt>.
|
||||
#
|
||||
# In your ERb templates, use this method to escape any unsafe content. For example:
|
||||
# <%=h @person.name %>
|
||||
#
|
||||
# ==== Example:
|
||||
# puts html_escape("is a > 0 & a < 10?")
|
||||
# # => is a > 0 & a < 10?
|
||||
def html_escape(s)
|
||||
s = s.to_s
|
||||
if s.html_safe?
|
||||
s
|
||||
else
|
||||
s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
undef :h
|
||||
alias h html_escape
|
||||
|
||||
module_function :html_escape
|
||||
module_function :h
|
||||
|
||||
# A utility method for escaping HTML entities in JSON strings.
|
||||
# This method is also aliased as <tt>j</tt>.
|
||||
#
|
||||
# In your ERb templates, use this method to escape any HTML entities:
|
||||
# <%=j @person.to_json %>
|
||||
#
|
||||
# ==== Example:
|
||||
# puts json_escape("is a > 0 & a < 10?")
|
||||
# # => is a \u003E 0 \u0026 a \u003C 10?
|
||||
def json_escape(s)
|
||||
s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
|
||||
end
|
||||
|
||||
alias j json_escape
|
||||
module_function :j
|
||||
module_function :json_escape
|
||||
end
|
||||
end
|
||||
|
||||
class Object
|
||||
def html_safe?
|
||||
false
|
||||
@@ -10,32 +60,46 @@ class Fixnum
|
||||
end
|
||||
end
|
||||
|
||||
class String
|
||||
attr_accessor :_rails_html_safe
|
||||
alias html_safe? _rails_html_safe
|
||||
module ActiveSupport #:nodoc:
|
||||
class SafeBuffer < String
|
||||
alias safe_concat concat
|
||||
|
||||
def concat(value)
|
||||
if value.html_safe?
|
||||
super(value)
|
||||
else
|
||||
super(ERB::Util.h(value))
|
||||
end
|
||||
end
|
||||
|
||||
def +(other)
|
||||
dup.concat(other)
|
||||
end
|
||||
|
||||
def <<(value)
|
||||
self.concat(value)
|
||||
end
|
||||
|
||||
def html_safe?
|
||||
true
|
||||
end
|
||||
|
||||
def html_safe
|
||||
self
|
||||
end
|
||||
|
||||
def to_s
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class String
|
||||
def html_safe!
|
||||
@_rails_html_safe = true
|
||||
self
|
||||
raise "You can't call html_safe! on a String"
|
||||
end
|
||||
|
||||
def html_safe
|
||||
dup.html_safe!
|
||||
ActiveSupport::SafeBuffer.new(self)
|
||||
end
|
||||
|
||||
alias original_plus +
|
||||
def +(other)
|
||||
result = original_plus(other)
|
||||
result._rails_html_safe = html_safe? && other.html_safe?
|
||||
result
|
||||
end
|
||||
|
||||
alias original_concat <<
|
||||
alias safe_concat <<
|
||||
def <<(other)
|
||||
@_rails_html_safe = false unless other.html_safe?
|
||||
result = original_concat(other)
|
||||
end
|
||||
|
||||
alias concat <<
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'active_support/core_ext/class/inheritable_attributes'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
require 'active_support/core_ext/proc'
|
||||
require 'active_support/core_ext/string/inflections'
|
||||
require 'active_support/core_ext/array/extract_options'
|
||||
@@ -9,7 +9,7 @@ module ActiveSupport
|
||||
extend Concern
|
||||
|
||||
included do
|
||||
class_inheritable_accessor :rescue_handlers
|
||||
class_attribute :rescue_handlers
|
||||
self.rescue_handlers = []
|
||||
end
|
||||
|
||||
@@ -67,7 +67,7 @@ module ActiveSupport
|
||||
end
|
||||
|
||||
# put the new handler at the end because the list is read in reverse
|
||||
rescue_handlers << [key, options[:with]]
|
||||
self.rescue_handlers += [[key, options[:with]]]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -83,7 +83,7 @@ module ActiveSupport
|
||||
def handler_for_rescue(exception)
|
||||
# We go from right to left because pairs are pushed onto rescue_handlers
|
||||
# as rescue_from declarations are found.
|
||||
_, rescuer = rescue_handlers.reverse.detect do |klass_name, handler|
|
||||
_, rescuer = self.class.rescue_handlers.reverse.detect do |klass_name, handler|
|
||||
# The purpose of allowing strings in rescue_from is to support the
|
||||
# declaration of handler associations for exception classes whose
|
||||
# definition is yet unknown.
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
ORIG_ARGV = ARGV.dup
|
||||
|
||||
begin
|
||||
require File.expand_path('../../../vendor/gems/environment', __FILE__)
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
||||
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
||||
require File.expand_path('../../../load_paths', __FILE__)
|
||||
|
||||
require 'test/unit'
|
||||
require 'mocha'
|
||||
|
||||
@@ -264,12 +264,12 @@ module CallbacksTest
|
||||
define_callbacks :save
|
||||
attr_reader :stuff
|
||||
|
||||
set_callback :save, :before, :omg, :per_key => {:if => :yes}
|
||||
set_callback :save, :before, :action, :per_key => {:if => :yes}
|
||||
|
||||
def yes() true end
|
||||
|
||||
def omg
|
||||
@stuff = "OMG"
|
||||
def action
|
||||
@stuff = "ACTION"
|
||||
end
|
||||
|
||||
def save
|
||||
@@ -522,7 +522,7 @@ module CallbacksTest
|
||||
def test_save
|
||||
obj = HyphenatedCallbacks.new
|
||||
obj.save
|
||||
assert_equal obj.stuff, "OMG"
|
||||
assert_equal obj.stuff, "ACTION"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
47
activesupport/test/core_ext/class/attribute_test.rb
Normal file
47
activesupport/test/core_ext/class/attribute_test.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
require 'abstract_unit'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
class ClassAttributeTest < ActiveSupport::TestCase
|
||||
class Base
|
||||
class_attribute :setting
|
||||
end
|
||||
|
||||
class Subclass < Base
|
||||
end
|
||||
|
||||
def setup
|
||||
@klass = Class.new { class_attribute :setting }
|
||||
@sub = Class.new(@klass)
|
||||
end
|
||||
|
||||
test 'defaults to nil' do
|
||||
assert_nil @klass.setting
|
||||
assert_nil @sub.setting
|
||||
end
|
||||
|
||||
test 'inheritable' do
|
||||
@klass.setting = 1
|
||||
assert_equal 1, @sub.setting
|
||||
end
|
||||
|
||||
test 'overridable' do
|
||||
@sub.setting = 1
|
||||
assert_nil @klass.setting
|
||||
|
||||
@klass.setting = 2
|
||||
assert_equal 1, @sub.setting
|
||||
|
||||
assert_equal 1, Class.new(@sub).setting
|
||||
end
|
||||
|
||||
test 'query method' do
|
||||
assert_equal false, @klass.setting?
|
||||
@klass.setting = 1
|
||||
assert_equal true, @klass.setting?
|
||||
end
|
||||
|
||||
test 'no instance delegates' do
|
||||
assert_raise(NoMethodError) { @klass.new.setting }
|
||||
assert_raise(NoMethodError) { @klass.new.setting? }
|
||||
end
|
||||
end
|
||||
@@ -342,12 +342,12 @@ class OutputSafetyTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "A string can be marked safe" do
|
||||
@string.html_safe!
|
||||
assert @string.html_safe?
|
||||
string = @string.html_safe
|
||||
assert string.html_safe?
|
||||
end
|
||||
|
||||
test "Marking a string safe returns the string" do
|
||||
assert_equal @string, @string.html_safe!
|
||||
assert_equal @string, @string.html_safe
|
||||
end
|
||||
|
||||
test "A fixnum is safe by default" do
|
||||
@@ -361,7 +361,7 @@ class OutputSafetyTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
@string.html_safe!
|
||||
@string.html_safe
|
||||
@string << klass.new
|
||||
|
||||
assert_equal "helloother", @string
|
||||
@@ -369,44 +369,44 @@ class OutputSafetyTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "Adding a safe string to another safe string returns a safe string" do
|
||||
@other_string = "other".html_safe!
|
||||
@string.html_safe!
|
||||
@combination = @other_string + @string
|
||||
@other_string = "other".html_safe
|
||||
string = @string.html_safe
|
||||
@combination = @other_string + string
|
||||
|
||||
assert_equal "otherhello", @combination
|
||||
assert @combination.html_safe?
|
||||
end
|
||||
|
||||
test "Adding an unsafe string to a safe string returns an unsafe string" do
|
||||
@other_string = "other".html_safe!
|
||||
@combination = @other_string + @string
|
||||
@other_combination = @string + @other_string
|
||||
test "Adding an unsafe string to a safe string escapes it and returns a safe string" do
|
||||
@other_string = "other".html_safe
|
||||
@combination = @other_string + "<foo>"
|
||||
@other_combination = @string + "<foo>"
|
||||
|
||||
assert_equal "otherhello", @combination
|
||||
assert_equal "helloother", @other_combination
|
||||
assert_equal "other<foo>", @combination
|
||||
assert_equal "hello<foo>", @other_combination
|
||||
|
||||
assert !@combination.html_safe?
|
||||
assert @combination.html_safe?
|
||||
assert !@other_combination.html_safe?
|
||||
end
|
||||
|
||||
test "Concatting safe onto unsafe yields unsafe" do
|
||||
@other_string = "other"
|
||||
@string.html_safe!
|
||||
@string.html_safe
|
||||
|
||||
@other_string.concat(@string)
|
||||
assert !@other_string.html_safe?
|
||||
end
|
||||
|
||||
test "Concatting unsafe onto safe yields unsafe" do
|
||||
@other_string = "other".html_safe!
|
||||
|
||||
@other_string.concat(@string)
|
||||
assert !@other_string.html_safe?
|
||||
test "Concatting unsafe onto safe yields escaped safe" do
|
||||
@other_string = "other".html_safe
|
||||
string = @other_string.concat("<foo>")
|
||||
assert_equal "other<foo>", string
|
||||
assert string.html_safe?
|
||||
end
|
||||
|
||||
test "Concatting safe onto safe yields safe" do
|
||||
@other_string = "other".html_safe!
|
||||
@string.html_safe!
|
||||
@other_string = "other".html_safe
|
||||
@string.html_safe
|
||||
|
||||
@other_string.concat(@string)
|
||||
assert @other_string.html_safe?
|
||||
@@ -414,31 +414,32 @@ class OutputSafetyTest < ActiveSupport::TestCase
|
||||
|
||||
test "Concatting safe onto unsafe with << yields unsafe" do
|
||||
@other_string = "other"
|
||||
@string.html_safe!
|
||||
@string.html_safe
|
||||
|
||||
@other_string << @string
|
||||
assert !@other_string.html_safe?
|
||||
end
|
||||
|
||||
test "Concatting unsafe onto safe with << yields unsafe" do
|
||||
@other_string = "other".html_safe!
|
||||
|
||||
@other_string << @string
|
||||
assert !@other_string.html_safe?
|
||||
test "Concatting unsafe onto safe with << yields escaped safe" do
|
||||
@other_string = "other".html_safe
|
||||
string = @other_string << "<foo>"
|
||||
assert_equal "other<foo>", string
|
||||
assert string.html_safe?
|
||||
end
|
||||
|
||||
test "Concatting safe onto safe with << yields safe" do
|
||||
@other_string = "other".html_safe!
|
||||
@string.html_safe!
|
||||
@other_string = "other".html_safe
|
||||
@string.html_safe
|
||||
|
||||
@other_string << @string
|
||||
assert @other_string.html_safe?
|
||||
end
|
||||
|
||||
test "Concatting a fixnum to safe always yields safe" do
|
||||
@string.html_safe!
|
||||
@string.concat(13)
|
||||
assert @string.html_safe?
|
||||
string = @string.html_safe
|
||||
string = string.concat(13)
|
||||
assert_equal "hello".concat(13), string
|
||||
assert string.html_safe?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
2
activesupport/test/fixtures/custom.rb
vendored
Normal file
2
activesupport/test/fixtures/custom.rb
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
class Custom
|
||||
end
|
||||
2
activesupport/test/fixtures/omgomg.rb
vendored
2
activesupport/test/fixtures/omgomg.rb
vendored
@@ -1,2 +0,0 @@
|
||||
class OmgOmg
|
||||
end
|
||||
@@ -59,15 +59,15 @@ elsif ENV['CHILD']
|
||||
end
|
||||
|
||||
test "resets requires one" do
|
||||
assert !defined?(OmgOmg)
|
||||
assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg"))
|
||||
assert !defined?(Custom)
|
||||
assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/custom/).size
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "custom"))
|
||||
end
|
||||
|
||||
test "resets requires two" do
|
||||
assert !defined?(OmgOmg)
|
||||
assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg"))
|
||||
assert !defined?(Custom)
|
||||
assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/custom/).size
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "custom"))
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
@@ -301,10 +301,10 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
|
||||
assert_equal " #{UNICODE_STRING}", @chars.rjust(5)
|
||||
assert_equal " #{UNICODE_STRING}", @chars.rjust(7)
|
||||
assert_equal "---#{UNICODE_STRING}", @chars.rjust(7, '-')
|
||||
assert_equal "ααα#{UNICODE_STRING}", @chars.rjust(7, 'α')
|
||||
assert_equal "αα#{UNICODE_STRING}", @chars.rjust(7, 'α')
|
||||
assert_equal "aba#{UNICODE_STRING}", @chars.rjust(7, 'ab')
|
||||
assert_equal "αηα#{UNICODE_STRING}", @chars.rjust(7, 'αη')
|
||||
assert_equal "αηαη#{UNICODE_STRING}", @chars.rjust(8, 'αη')
|
||||
assert_equal "αη#{UNICODE_STRING}", @chars.rjust(8, 'αη')
|
||||
end
|
||||
|
||||
def test_ljust_should_raise_argument_errors_on_bad_arguments
|
||||
@@ -319,10 +319,10 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
|
||||
assert_equal "#{UNICODE_STRING} ", @chars.ljust(5)
|
||||
assert_equal "#{UNICODE_STRING} ", @chars.ljust(7)
|
||||
assert_equal "#{UNICODE_STRING}---", @chars.ljust(7, '-')
|
||||
assert_equal "#{UNICODE_STRING}ααα", @chars.ljust(7, 'α')
|
||||
assert_equal "#{UNICODE_STRING}αα", @chars.ljust(7, 'α')
|
||||
assert_equal "#{UNICODE_STRING}aba", @chars.ljust(7, 'ab')
|
||||
assert_equal "#{UNICODE_STRING}αηα", @chars.ljust(7, 'αη')
|
||||
assert_equal "#{UNICODE_STRING}αηαη", @chars.ljust(8, 'αη')
|
||||
assert_equal "#{UNICODE_STRING}αη", @chars.ljust(8, 'αη')
|
||||
end
|
||||
|
||||
def test_center_should_raise_argument_errors_on_bad_arguments
|
||||
@@ -339,13 +339,13 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
|
||||
assert_equal " #{UNICODE_STRING} ", @chars.center(7)
|
||||
assert_equal "--#{UNICODE_STRING}--", @chars.center(8, '-')
|
||||
assert_equal "--#{UNICODE_STRING}---", @chars.center(9, '-')
|
||||
assert_equal "αα#{UNICODE_STRING}αα", @chars.center(8, 'α')
|
||||
assert_equal "αα#{UNICODE_STRING}ααα", @chars.center(9, 'α')
|
||||
assert_equal "a#{UNICODE_STRING}ab", @chars.center(7, 'ab')
|
||||
assert_equal "ab#{UNICODE_STRING}ab", @chars.center(8, 'ab')
|
||||
assert_equal "abab#{UNICODE_STRING}abab", @chars.center(12, 'ab')
|
||||
assert_equal "α#{UNICODE_STRING}αη", @chars.center(7, 'αη')
|
||||
assert_equal "αη#{UNICODE_STRING}αη", @chars.center(8, 'αη')
|
||||
assert_equal "α#{UNICODE_STRING}α", @chars.center(8, 'α')
|
||||
assert_equal "α#{UNICODE_STRING}αα", @chars.center(9, 'α')
|
||||
assert_equal "a#{UNICODE_STRING}", @chars.center(7, 'ab')
|
||||
assert_equal UNICODE_STRING, @chars.center(8, 'ab')
|
||||
assert_equal "ab#{UNICODE_STRING}ab", @chars.center(12, 'ab')
|
||||
assert_equal "α#{UNICODE_STRING}", @chars.center(7, 'αη')
|
||||
assert_equal UNICODE_STRING, @chars.center(8, 'αη')
|
||||
end
|
||||
|
||||
def test_lstrip_strips_whitespace_from_the_left_of_the_string
|
||||
|
||||
@@ -77,7 +77,7 @@ module Notifications
|
||||
def test_instrument_with_bang_returns_result_even_on_failure
|
||||
begin
|
||||
instrument!(:awesome, :payload => "notifications") do
|
||||
raise "OMG"
|
||||
raise "FAIL"
|
||||
end
|
||||
flunk
|
||||
rescue
|
||||
@@ -126,10 +126,10 @@ module Notifications
|
||||
def test_instrument_does_not_publish_when_exception_is_raised
|
||||
begin
|
||||
instrument(:awesome, :payload => "notifications") do
|
||||
raise "OMG"
|
||||
raise "FAIL"
|
||||
end
|
||||
rescue RuntimeError => e
|
||||
assert_equal "OMG", e.message
|
||||
assert_equal "FAIL", e.message
|
||||
end
|
||||
|
||||
drain
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
class SafeBufferTest < ActionView::TestCase
|
||||
class SafeBufferTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
@buffer = ActionView::SafeBuffer.new
|
||||
@buffer = ActiveSupport::SafeBuffer.new
|
||||
end
|
||||
|
||||
test "Should look like a string" do
|
||||
@@ -16,7 +16,7 @@ class SafeBufferTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
test "Should NOT escape a safe value passed to it" do
|
||||
@buffer << "<script>".html_safe!
|
||||
@buffer << "<script>".html_safe
|
||||
assert_equal "<script>", @buffer
|
||||
end
|
||||
|
||||
@@ -36,6 +36,6 @@ class SafeBufferTest < ActionView::TestCase
|
||||
|
||||
test "Should return a safe buffer when calling to_s" do
|
||||
new_buffer = @buffer.to_s
|
||||
assert_equal ActionView::SafeBuffer, new_buffer.class
|
||||
assert_equal ActiveSupport::SafeBuffer, new_buffer.class
|
||||
end
|
||||
end
|
||||
@@ -7,26 +7,25 @@ def root_dir
|
||||
end
|
||||
|
||||
def rake(*tasks)
|
||||
tasks.each { |task| return false unless system("#{root_dir}/bin/rake", task) }
|
||||
tasks.each { |task| return false unless system("bundle exec rake", task) }
|
||||
true
|
||||
end
|
||||
|
||||
puts "[CruiseControl] Rails build"
|
||||
build_results = {}
|
||||
|
||||
# Requires gem home and path to be writeable and/or overridden to be ~/.gem,
|
||||
# Will enable when RubyGems supports this properly (in a coming release)
|
||||
# build_results[:geminstaller] = system 'geminstaller --exceptions'
|
||||
# Install rubygems-update, so 'gem update --system' in cruise_config.rb auto-installs it on next build.
|
||||
# This is how you can auto-update rubygems without logging in to CI system
|
||||
build_results[:geminstaller] = system "sudo gem install rubygems-update -v 1.3.5 --no-ri --no-rdoc"
|
||||
|
||||
# for now, use the no-passwd sudoers approach (documented in ci_setup_notes.txt)
|
||||
# A security hole, but there is nothing valuable on rails CI box anyway.
|
||||
build_results[:geminstaller] = system "sudo geminstaller --config=#{root_dir}/ci/geminstaller.yml --exceptions"
|
||||
# Install required version of bundler.
|
||||
build_results[:geminstaller] = system "sudo gem install bundler -v 0.9.0.pre3 --prerelease --no-ri --no-rdoc"
|
||||
|
||||
cd root_dir do
|
||||
puts
|
||||
puts "[CruiseControl] Bundling RubyGems"
|
||||
puts
|
||||
build_results[:bundle] = system 'rm -rf vendor && env CI=1 gem bundle --update && chmod 755 bin vendor vendor/gems'
|
||||
build_results[:bundle] = system 'env CI=1 sudo bundle install'
|
||||
end
|
||||
|
||||
cd "#{root_dir}/activesupport" do
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
gems:
|
||||
- name: geminstaller
|
||||
version: >= 0.4.3
|
||||
- name: rubygems-update
|
||||
version: >= 1.3.5
|
||||
- name: bundler
|
||||
version: >= 0.7.1
|
||||
21
load_paths.rb
Normal file
21
load_paths.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
begin
|
||||
require File.expand_path('../vendor/environment', __FILE__)
|
||||
rescue LoadError
|
||||
begin
|
||||
require 'rubygems'
|
||||
require 'bundler'
|
||||
Bundler.setup
|
||||
rescue LoadError
|
||||
%w(
|
||||
actionmailer
|
||||
actionpack
|
||||
activemodel
|
||||
activerecord
|
||||
activeresource
|
||||
activesupport
|
||||
railties
|
||||
).each do |framework|
|
||||
$:.unshift File.expand_path("../#{framework}/lib", __FILE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
|
||||
s.add_dependency('activeresource', '= 3.0.pre')
|
||||
s.add_dependency('actionmailer', '= 3.0.pre')
|
||||
s.add_dependency('railties', '= 3.0.pre')
|
||||
s.add_dependency('bundler', '>= 0.9.0.pre')
|
||||
|
||||
s.rdoc_options << '--exclude' << '.'
|
||||
s.has_rdoc = false
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
begin
|
||||
require File.expand_path('../../vendor/gems/environment', __FILE__)
|
||||
rescue LoadError
|
||||
end
|
||||
require File.expand_path('../../load_paths', __FILE__)
|
||||
|
||||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
class Rails::InfoController < ActionController::Base
|
||||
def properties
|
||||
if consider_all_requests_local || local_request?
|
||||
if consider_all_requests_local? || local_request?
|
||||
render :inline => Rails::Info.to_html
|
||||
else
|
||||
render :text => '<p>For security purposes, this information is only available to local requests.</p>', :status => :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def consider_all_requests_local?
|
||||
Rails.application.config.consider_all_requests_local
|
||||
end
|
||||
end
|
||||
|
||||
@@ -88,7 +88,7 @@ Please note that you need to +git :init+ before you can install a plugin as a su
|
||||
Or use plain old SVN :
|
||||
|
||||
<ruby>
|
||||
plugin 'wtfsvn', :svn => 'svn://crap.com/wtf/trunk'
|
||||
plugin 'usingsvn', :svn => 'svn://example.com/usingsvn/trunk'
|
||||
</ruby>
|
||||
|
||||
h4. vendor/lib/file/initializer(filename, data = nil, &block)
|
||||
|
||||
@@ -90,6 +90,18 @@ module Rails::Generators
|
||||
template "config/boot.rb"
|
||||
end
|
||||
|
||||
def gem_for_database
|
||||
# %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
|
||||
case options[:database]
|
||||
when "mysql" then "mysql"
|
||||
when "oracle" then "ruby-oci8"
|
||||
when "postgresql" then "pg"
|
||||
when "sqlite3" then "sqlite3-ruby"
|
||||
when "frontbase" then "ruby-frontbase"
|
||||
when "ibm_db" then "ibm_db"
|
||||
end
|
||||
end
|
||||
|
||||
def create_activerecord_files
|
||||
return if options[:skip_activerecord]
|
||||
template "config/databases/#{options[:database]}.yml", "config/database.yml"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Edit this Gemfile to bundle your application's dependencies.
|
||||
source :gemcutter
|
||||
|
||||
<% if !dev_or_edge? %>
|
||||
gem "rails", "<%= Rails::VERSION::STRING %>"
|
||||
<% end -%>
|
||||
@@ -11,6 +13,14 @@ gem "rails", "<%= Rails::VERSION::STRING %>"
|
||||
<%= "# " unless options.edge? %>gem "rails", :git => "git://github.com/rails/rails.git"
|
||||
<%- end -%>
|
||||
|
||||
<% unless options[:skip_activerecord] -%>
|
||||
<% if options[:database] == 'sqlite3' -%>
|
||||
# ActiveRecord requires a database adapter. By default,
|
||||
# Rails has selected sqlite3.
|
||||
<% end -%>
|
||||
gem "<%= gem_for_database %>"
|
||||
<% end -%>
|
||||
|
||||
## Bundle the gems you use:
|
||||
# gem "bj"
|
||||
# gem "hpricot", "0.6"
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
# Use Bundler (preferred)
|
||||
environment = File.expand_path('../../vendor/gems/environment', __FILE__)
|
||||
if File.exist?("#{environment}.rb")
|
||||
require environment
|
||||
|
||||
# Use 2.x style vendor/rails and RubyGems
|
||||
else
|
||||
vendor_rails = File.expand_path('../../vendor/rails', __FILE__)
|
||||
if File.exist?(vendor_rails)
|
||||
Dir["#{vendor_rails}/*/lib"].each { |path| $:.unshift(path) }
|
||||
end
|
||||
|
||||
begin
|
||||
require File.expand_path('../../vendor/environment', __FILE__)
|
||||
rescue LoadError
|
||||
require 'rubygems'
|
||||
require 'bundler'
|
||||
Bundler.setup
|
||||
|
||||
# To use 2.x style vendor/rails and RubyGems
|
||||
#
|
||||
# vendor_rails = File.expand_path('../../vendor/rails', __FILE__)
|
||||
# if File.exist?(vendor_rails)
|
||||
# Dir["#{vendor_rails}/*/lib"].each { |path| $:.unshift(path) }
|
||||
# end
|
||||
#
|
||||
# require 'rubygems'
|
||||
end
|
||||
|
||||
<% unless options[:skip_activerecord] -%>
|
||||
|
||||
@@ -5,7 +5,7 @@ module Rails
|
||||
class Configuration < ::Rails::Engine::Configuration
|
||||
include ::Rails::Configuration::Deprecated
|
||||
|
||||
attr_accessor :cache_classes, :cache_store, :colorize_logging,
|
||||
attr_accessor :allow_concurrency, :cache_classes, :cache_store, :colorize_logging,
|
||||
:consider_all_requests_local, :dependency_loading,
|
||||
:filter_parameters, :log_level, :logger, :metals,
|
||||
:plugins, :preload_frameworks, :reload_engines, :reload_plugins,
|
||||
@@ -13,11 +13,13 @@ module Rails
|
||||
|
||||
def initialize(*)
|
||||
super
|
||||
@allow_concurrency = false
|
||||
@colorize_logging = true
|
||||
@filter_parameters = []
|
||||
@dependency_loading = true
|
||||
@serve_static_assets = true
|
||||
@time_zone = "UTC"
|
||||
@consider_all_requests_local = true
|
||||
end
|
||||
|
||||
def paths
|
||||
@@ -50,7 +52,7 @@ module Rails
|
||||
self.preload_frameworks = true
|
||||
self.cache_classes = true
|
||||
self.dependency_loading = false
|
||||
self.action_controller.allow_concurrency = true if respond_to?(:action_controller)
|
||||
self.allow_concurrency = true
|
||||
self
|
||||
end
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ module Rails
|
||||
def middleware
|
||||
@@default_middleware_stack ||= ActionDispatch::MiddlewareStack.new.tap do |middleware|
|
||||
middleware.use('::ActionDispatch::Static', lambda { Rails.public_path }, :if => lambda { Rails.application.config.serve_static_assets })
|
||||
middleware.use('::Rack::Lock', :if => lambda { !ActionController::Base.allow_concurrency })
|
||||
middleware.use('::Rack::Lock', :if => lambda { !Rails.application.config.allow_concurrency })
|
||||
middleware.use('::Rack::Runtime')
|
||||
middleware.use('::Rails::Rack::Logger')
|
||||
middleware.use('::ActionDispatch::ShowExceptions', lambda { ActionController::Base.consider_all_requests_local })
|
||||
middleware.use('::ActionDispatch::ShowExceptions', lambda { Rails.application.config.consider_all_requests_local })
|
||||
middleware.use('::ActionDispatch::Callbacks', lambda { !Rails.application.config.cache_classes })
|
||||
middleware.use('::ActionDispatch::Cookies')
|
||||
middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options })
|
||||
@@ -88,11 +88,12 @@ module Rails
|
||||
end
|
||||
|
||||
class Generators #:nodoc:
|
||||
attr_accessor :aliases, :options, :colorize_logging
|
||||
attr_accessor :aliases, :options, :fallbacks, :colorize_logging
|
||||
|
||||
def initialize
|
||||
@aliases = Hash.new { |h,k| h[k] = {} }
|
||||
@options = Hash.new { |h,k| h[k] = {} }
|
||||
@fallbacks = {}
|
||||
@colorize_logging = true
|
||||
end
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ module Rails
|
||||
no_color! unless config.colorize_logging
|
||||
aliases.deep_merge! config.aliases
|
||||
options.deep_merge! config.options
|
||||
fallbacks.merge! config.fallbacks
|
||||
end
|
||||
|
||||
def self.aliases #:nodoc:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'active_support/core_ext/class/inheritable_attributes'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
require 'active_support/core_ext/hash/reverse_merge'
|
||||
require 'rails/generators'
|
||||
require 'fileutils'
|
||||
@@ -28,8 +29,8 @@ module Rails
|
||||
class TestCase < ActiveSupport::TestCase
|
||||
include FileUtils
|
||||
|
||||
extlib_inheritable_accessor :destination_root, :current_path, :generator_class,
|
||||
:default_arguments, :instance_writer => false
|
||||
class_attribute :destination_root, :current_path, :generator_class, :default_arguments
|
||||
delegate :destination_root, :current_path, :generator_class, :default_arguments, :to => :'self.class'
|
||||
|
||||
# Generators frequently change the current path using +FileUtils.cd+.
|
||||
# So we need to store the path at file load and revert back to it after each test.
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
ORIG_ARGV = ARGV.dup
|
||||
|
||||
root = File.expand_path('../../..', __FILE__)
|
||||
begin
|
||||
require "#{root}/vendor/gems/environment"
|
||||
rescue LoadError
|
||||
%w(activesupport activemodel activerecord actionpack actionmailer activeresource railties).each do |lib|
|
||||
$:.unshift "#{root}/#{lib}/lib"
|
||||
end
|
||||
end
|
||||
|
||||
$:.unshift "#{root}/railties/builtin/rails_info"
|
||||
require File.expand_path("../../../load_paths", __FILE__)
|
||||
$:.unshift File.expand_path("../../builtin/rails_info", __FILE__)
|
||||
|
||||
require 'stringio'
|
||||
require 'test/unit'
|
||||
|
||||
@@ -93,7 +93,7 @@ module ApplicationTests
|
||||
RUBY
|
||||
|
||||
require "#{app_path}/config/application"
|
||||
assert AppTemplate::Application.config.action_controller.allow_concurrency
|
||||
assert AppTemplate::Application.config.allow_concurrency
|
||||
end
|
||||
|
||||
test "the application can be marked as threadsafe when there are no frameworks" do
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user