提交 03a62f4a 编写于 作者: P Pratik Naik

Merge remote branch 'mainstream/master'

......@@ -605,7 +605,7 @@ def collect_responses_and_parts_order(headers) #:nodoc:
each_template(templates_path, templates_name) do |template|
responses << {
:body => render(:_template => template),
:body => render(:template => template),
:content_type => template.mime_type.to_s
}
end
......
......@@ -207,7 +207,7 @@ def create_parts
@parts.unshift create_inline_part(@body)
elsif @parts.empty? || @parts.all? { |p| p.content_disposition =~ /^attachment/ }
lookup_context.find_all(@template, @mailer_name).each do |template|
@parts << create_inline_part(render(:_template => template), template.mime_type)
@parts << create_inline_part(render(:template => template), template.mime_type)
end
if @parts.size > 1
......
......@@ -2,6 +2,8 @@
require 'abstract_unit'
class BaseTest < ActiveSupport::TestCase
# TODO Add some tests for implicity layout render and url helpers
# so we can get rid of old base tests altogether with old base.
class BaseMailer < ActionMailer::Base
self.mailer_name = "base_mailer"
......
......@@ -444,9 +444,6 @@ def test_custom_templating_extension
expected.from = "system@loudthinking.com"
expected.date = Time.local(2004, 12, 12)
# Stub the render method so no alternative renderers need be present.
ActionView::Base.any_instance.stubs(:render).returns("Hello there, \n\nMr. #{@recipient}")
# Now that the template is registered, there should be one part. The text/plain part.
created = nil
assert_nothing_raised { created = TestMailer.custom_templating_extension(@recipient) }
......
......@@ -12,6 +12,7 @@
module AbstractController
extend ActiveSupport::Autoload
autoload :Assigns
autoload :Base
autoload :Callbacks
autoload :Collector
......
module AbstractController
module Assigns
# This method should return a hash with assigns.
# You can overwrite this configuration per controller.
# :api: public
def view_assigns
hash = {}
variables = instance_variable_names
variables -= protected_instance_variables if respond_to?(:protected_instance_variables)
variables.each { |name| hash[name] = instance_variable_get(name) }
hash
end
# This method assigns the hash specified in _assigns_hash to the given object.
# :api: private
# TODO Ideally, this should be done on AV::Base.new initialization.
def _evaluate_assigns(object)
view_assigns.each { |k,v| object.instance_variable_set(k, v) }
end
end
end
\ No newline at end of file
......@@ -284,6 +284,12 @@ def _normalize_options(options)
layout = options.key?(:layout) ? options.delete(:layout) : :default
value = _layout_for_option(layout)
options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value
# TODO Layout for partials should be handled here, because inside the
# partial renderer it looks for the layout as a partial.
if options.key?(:partial) && options[:layout]
options[:layout] = view_context.find_layout(options[:layout])
end
end
end
......
......@@ -31,6 +31,8 @@ def locale=(value)
module Rendering
extend ActiveSupport::Concern
include AbstractController::Assigns
include AbstractController::ViewPaths
# Overwrite process to setup I18n proxy.
......@@ -54,8 +56,8 @@ def view_context
@_view_context ||= ActionView::Base.for_controller(self)
end
# Mostly abstracts the fact that calling render twice is a DoubleRenderError.
# Delegates render_to_body and sticks the result in self.response_body.
# Normalize arguments, options and then delegates render_to_body and
# sticks the result in self.response_body.
def render(*args, &block)
options = _normalize_args(*args, &block)
_normalize_options(options)
......@@ -78,8 +80,10 @@ def render_to_string(options={})
end
# Find and renders a template based on the options given.
def _render_template(options)
view_context.render_template(options) { |template| _with_template_hook(template) }
# :api: private
def _render_template(options) #:nodoc:
_evaluate_assigns(view_context)
view_context.render(options)
end
# The prefix used in render "foo" shortcuts.
......@@ -134,9 +138,5 @@ def _normalize_options(options)
def _process_options(options)
end
def _with_template_hook(template)
self.formats = template.formats
end
end
end
......@@ -7,7 +7,7 @@ module ViewPaths
self._view_paths = ActionView::PathSet.new
end
delegate :template_exists?, :view_paths, :formats, :formats=,
delegate :find_template, :template_exists?, :view_paths, :formats, :formats=,
:locale, :locale=, :to => :lookup_context
# LookupContext is the object responsible to hold all information required to lookup
......@@ -29,10 +29,6 @@ def prepend_view_path(path)
lookup_context.view_paths.unshift(*path)
end
def template_exists?(*args)
lookup_context.exists?(*args)
end
module ClassMethods
# Append a path to the list of view paths for this controller.
#
......
......@@ -2,7 +2,6 @@ module ActionController
class Base < Metal
abstract!
include AbstractController::Callbacks
include AbstractController::Layouts
include AbstractController::Translation
......@@ -23,6 +22,7 @@ class Base < Metal
# Rails 2.x compatibility
include ActionController::Compatibility
include ActionController::ImplicitRender
include ActionController::Cookies
include ActionController::Flash
......@@ -36,8 +36,12 @@ class Base < Metal
# Add instrumentations hooks at the bottom, to ensure they instrument
# all the methods properly.
include ActionController::Instrumentation
include ImplicitRender
# Before callbacks should also be executed the earliest as possible, so
# also include them at the bottom.
include AbstractController::Callbacks
# The same with rescue, append it at the end to wrap as much as possible.
include ActionController::Rescue
def self.inherited(klass)
......
......@@ -41,9 +41,7 @@ def fragment_for(buffer, name = {}, options = nil, &block) #:nodoc:
else
pos = buffer.length
block.call
content = buffer[pos..-1]
content = content.as_str if content.respond_to?(:as_str)
write_fragment(name, content, options)
write_fragment(name, buffer[pos..-1], options)
end
else
block.call
......@@ -53,9 +51,10 @@ def fragment_for(buffer, name = {}, options = nil, &block) #:nodoc:
# Writes <tt>content</tt> to the location signified by <tt>key</tt> (see <tt>expire_fragment</tt> for acceptable formats)
def write_fragment(key, content, options = nil)
return content unless cache_configured?
key = fragment_cache_key(key)
key = fragment_cache_key(key)
instrument_fragment_cache :write_fragment, key do
content = content.html_safe.to_str if content.respond_to?(:html_safe)
cache_store.write(key, content, options)
end
content
......@@ -64,10 +63,11 @@ def write_fragment(key, content, options = nil)
# Reads a cached fragment from the location signified by <tt>key</tt> (see <tt>expire_fragment</tt> for acceptable formats)
def read_fragment(key, options = nil)
return unless cache_configured?
key = fragment_cache_key(key)
key = fragment_cache_key(key)
instrument_fragment_cache :read_fragment, key do
cache_store.read(key, options)
result = cache_store.read(key, options)
result.respond_to?(:html_safe) ? result.html_safe : result
end
end
......
......@@ -261,6 +261,7 @@ def retrieve_response_from_mimes(mimes=nil, &block)
block.call(collector) if block_given?
if format = request.negotiate_mime(collector.order)
self.content_type ||= format.to_s
self.formats = [format.to_sym]
collector.response_for(format)
else
......
......@@ -87,8 +87,9 @@ def self._write_render_options
end
add :update do |proc, options|
_evaluate_assigns(view_context)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
self.content_type = Mime::JS
self.content_type = Mime::JS
self.response_body = generator.to_s
end
end
......
......@@ -5,26 +5,31 @@ module Rendering
include ActionController::RackDelegation
include AbstractController::Rendering
def process(*)
# Before processing, set the request formats in current controller formats.
def process_action(*) #:nodoc:
self.formats = request.formats.map { |x| x.to_sym }
super
end
def render(*args)
# Check for double render errors and set the content_type after rendering.
def render(*args) #:nodoc:
raise ::AbstractController::DoubleRenderError if response_body
super
self.content_type ||= Mime[formats.first].to_s
response_body
end
private
def _normalize_args(action=nil, options={}, &blk)
# Normalize arguments by catching blocks and setting them on :update.
def _normalize_args(action=nil, options={}, &blk) #:nodoc:
options = super
options[:update] = blk if block_given?
options
end
def _normalize_options(options)
# Normalize both text and status options.
def _normalize_options(options) #:nodoc:
if options.key?(:text) && options[:text].respond_to?(:to_text)
options[:text] = options[:text].to_text
end
......@@ -36,7 +41,8 @@ def _normalize_options(options)
super
end
def _process_options(options)
# Process controller specific options, as status, content-type and location.
def _process_options(options) #:nodoc:
status, content_type, location = options.values_at(:status, :content_type, :location)
self.status = status if status
......@@ -46,10 +52,5 @@ def _process_options(options)
super
end
def _with_template_hook(template)
super
self.content_type ||= template.mime_type.to_s
end
end
end
......@@ -362,11 +362,11 @@ def self.default_actions
attr_reader :plural, :singular, :options
def initialize(entities, options = {})
entities = entities.to_s
@name = entities.to_s
@options = options
@plural = entities.pluralize
@singular = entities.singularize
@plural = @name.pluralize
@singular = @name.singularize
end
def default_actions
......@@ -393,7 +393,7 @@ def action_type(action)
end
def name
options[:as] || plural
options[:as] || @name
end
def controller
......@@ -438,8 +438,8 @@ def action_type(action)
end
end
def name
options[:as] || singular
def member_name
name
end
end
......@@ -468,8 +468,8 @@ def resource(*resources, &block)
post :create if resource.actions.include?(:create)
put :update if resource.actions.include?(:update)
delete :destroy if resource.actions.include?(:destroy)
get :new, :as => resource.singular if resource.actions.include?(:new)
get :edit, :as => resource.singular if resource.actions.include?(:edit)
get :new, :as => resource.name if resource.actions.include?(:new)
get :edit, :as => resource.name if resource.actions.include?(:edit)
end
end
......
......@@ -194,7 +194,7 @@ class << self
attr_accessor :base_path, :assigns, :template_extension, :lookup_context
attr_internal :captures, :request, :layout, :controller, :template, :config
delegate :find, :exists?, :formats, :formats=, :locale, :locale=,
delegate :find_template, :template_exists?, :formats, :formats=, :locale, :locale=,
:view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
......@@ -264,14 +264,5 @@ def punctuate_body!(part)
response.body_parts << part
nil
end
# Evaluates the local assigns and controller ivars, pushes them to the view.
def _evaluate_assigns_and_ivars #:nodoc:
if controller
variables = controller.instance_variable_names
variables -= controller.protected_instance_variables if controller.respond_to?(:protected_instance_variables)
variables.each { |name| instance_variable_set(name, controller.instance_variable_get(name)) }
end
end
end
end
......@@ -129,7 +129,7 @@ def error_message_on(object, method, *args)
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
(errors = obj.errors[method])
content_tag("div",
(options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]),
"#{options[:prepend_text]}#{ERB::Util.h(errors.first)}#{options[:append_text]}".html_safe,
:class => options[:css_class]
)
else
......
......@@ -242,12 +242,12 @@ def javascript_path(source)
# == Caching multiple javascripts into one
#
# You can also cache multiple javascripts into one file, which requires less HTTP connections to download and can better be
# compressed by gzip (leading to faster transfers). Caching will only happen if ActionController::Base.perform_caching
# compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching
# is set to <tt>true</tt> (which is the case by default for the Rails production environment, but not for the development
# environment).
#
# ==== Examples
# javascript_include_tag :all, :cache => true # when ActionController::Base.perform_caching is false =>
# javascript_include_tag :all, :cache => true # when config.perform_caching is false =>
# <script type="text/javascript" src="/javascripts/prototype.js"></script>
# <script type="text/javascript" src="/javascripts/effects.js"></script>
# ...
......@@ -255,15 +255,15 @@ def javascript_path(source)
# <script type="text/javascript" src="/javascripts/shop.js"></script>
# <script type="text/javascript" src="/javascripts/checkout.js"></script>
#
# javascript_include_tag :all, :cache => true # when ActionController::Base.perform_caching is true =>
# javascript_include_tag :all, :cache => true # when config.perform_caching is true =>
# <script type="text/javascript" src="/javascripts/all.js"></script>
#
# javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when ActionController::Base.perform_caching is false =>
# javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is false =>
# <script type="text/javascript" src="/javascripts/prototype.js"></script>
# <script type="text/javascript" src="/javascripts/cart.js"></script>
# <script type="text/javascript" src="/javascripts/checkout.js"></script>
#
# javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when ActionController::Base.perform_caching is true =>
# javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is true =>
# <script type="text/javascript" src="/javascripts/shop.js"></script>
#
# The <tt>:recursive</tt> option is also available for caching:
......@@ -275,11 +275,11 @@ def javascript_include_tag(*sources)
cache = concat || options.delete("cache")
recursive = options.delete("recursive")
if concat || (ActionController::Base.perform_caching && cache)
if concat || (config.perform_caching && cache)
joined_javascript_name = (cache == true ? "all" : cache) + ".js"
joined_javascript_path = File.join(joined_javascript_name[/^#{File::SEPARATOR}/] ? config.assets_dir : config.javascripts_dir, joined_javascript_name)
unless ActionController::Base.perform_caching && File.exists?(joined_javascript_path)
unless config.perform_caching && File.exists?(joined_javascript_path)
write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive))
end
javascript_src_tag(joined_javascript_name, options)
......@@ -390,25 +390,25 @@ def stylesheet_path(source)
# == Caching multiple stylesheets into one
#
# You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be
# compressed by gzip (leading to faster transfers). Caching will only happen if ActionController::Base.perform_caching
# compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching
# is set to true (which is the case by default for the Rails production environment, but not for the development
# environment). Examples:
#
# ==== Examples
# stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is false =>
# stylesheet_link_tag :all, :cache => true # when config.perform_caching is false =>
# <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" type="text/css" />
# <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" type="text/css" />
# <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" />
#
# stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is true =>
# stylesheet_link_tag :all, :cache => true # when config.perform_caching is true =>
# <link href="/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" />
#
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when ActionController::Base.perform_caching is false =>
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is false =>
# <link href="/stylesheets/shop.css" media="screen" rel="stylesheet" type="text/css" />
# <link href="/stylesheets/cart.css" media="screen" rel="stylesheet" type="text/css" />
# <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" type="text/css" />
#
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when ActionController::Base.perform_caching is true =>
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is true =>
# <link href="/stylesheets/payment.css" media="screen" rel="stylesheet" type="text/css" />
#
# The <tt>:recursive</tt> option is also available for caching:
......@@ -426,11 +426,11 @@ def stylesheet_link_tag(*sources)
cache = concat || options.delete("cache")
recursive = options.delete("recursive")
if concat || (ActionController::Base.perform_caching && cache)
if concat || (config.perform_caching && cache)
joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
joined_stylesheet_path = File.join(joined_stylesheet_name[/^#{File::SEPARATOR}/] ? config.assets_dir : config.stylesheets_dir, joined_stylesheet_name)
unless ActionController::Base.perform_caching && File.exists?(joined_stylesheet_path)
unless config.perform_caching && File.exists?(joined_stylesheet_path)
write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive))
end
stylesheet_tag(joined_stylesheet_name, options)
......
......@@ -140,7 +140,7 @@ def content_for?(name)
def with_output_buffer(buf = nil) #:nodoc:
unless buf
buf = ActionView::OutputBuffer.new
buf.force_encoding(output_buffer.encoding) if buf.respond_to?(:force_encoding)
buf.force_encoding(output_buffer.encoding) if output_buffer && buf.respond_to?(:force_encoding)
end
self.output_buffer, old_buffer = buf, output_buffer
yield
......
......@@ -180,7 +180,6 @@ def remote_function(options)
# #include_helpers_from_context has nothing to overwrite.
class JavaScriptGenerator #:nodoc:
def initialize(context, &block) #:nodoc:
context._evaluate_assigns_and_ivars
@context, @lines = context, []
@context.update_details(:formats => [:js, :html]) do
include_helpers_from_context
......
......@@ -109,7 +109,7 @@ def escape_once(html)
def content_tag_string(name, content, options, escape = true)
tag_options = tag_options(options, escape) if options
("<#{name}#{tag_options}>".html_safe << content.to_s).safe_concat("</#{name}>")
"<#{name}#{tag_options}>#{ERB::Util.h(content)}</#{name}>".html_safe
end
def tag_options(options, escape = true)
......
......@@ -224,7 +224,7 @@ def link_to(*args, &block)
end
href_attr = "href=\"#{url}\"" unless href
("<a #{href_attr}#{tag_options}>".html_safe << (name || url)).safe_concat("</a>")
"<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe
end
end
......
......@@ -38,17 +38,18 @@ module Setters #:nodoc:
register_detail(:locale) { [I18n.locale] }
class DetailsKey #:nodoc:
attr_reader :details
alias :eql? :equal?
alias :object_hash :hash
attr_reader :hash
@details_keys = Hash.new
def self.get(details)
@details_keys[details] ||= new(details)
@details_keys[details] ||= new
end
def initialize(details)
@details, @hash = details, details.hash
def initialize
@hash = object_hash
end
end
......@@ -70,6 +71,7 @@ def view_paths=(paths)
def find(name, prefix = nil, partial = false)
@view_paths.find(name, prefix, partial, details, details_key)
end
alias :find_template :find
def find_all(name, prefix = nil, partial = false)
@view_paths.find_all(name, prefix, partial, details, details_key)
......@@ -78,6 +80,7 @@ def find_all(name, prefix = nil, partial = false)
def exists?(name, prefix = nil, partial = false)
@view_paths.exists?(name, prefix, partial, details, details_key)
end
alias :template_exists? :exists?
# Add fallbacks to the view paths. Useful in cases you are rendering a :file.
def with_fallbacks
......
require 'active_support/core_ext/object/try'
module ActionView
module Layouts
# You can think of a layout as a method that is called with a block. _layout_for
# returns the contents that are yielded to the layout. If the user calls yield
# :some_name, the block, by default, returns content_for(:some_name). If the user
......@@ -46,13 +43,13 @@ def _layout_for(name = nil, &block) #:nodoc:
# This is the method which actually finds the layout using details in the lookup
# context object. If no layout is found, it checkes if at least a layout with
# the given name exists across all details before raising the error.
def _find_layout(layout) #:nodoc:
def find_layout(layout) #:nodoc:
begin
layout =~ /^\// ?
with_fallbacks { find(layout) } : find(layout)
with_fallbacks { find_template(layout) } : find_template(layout)
rescue ActionView::MissingTemplate => e
update_details(:formats => nil) do
raise unless exists?(layout)
raise unless template_exists?(layout)
end
end
end
......
......@@ -294,7 +294,7 @@ def collection
def find_template(path=@path)
return path unless path.is_a?(String)
prefix = @view.controller_path unless path.include?(?/)
@view.find(path, prefix, true)
@view.find_template(path, prefix, true)
end
def partial_path(object = @object)
......
......@@ -12,14 +12,18 @@ module Rendering
#
# If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
# as the locals hash.
def render(options = {}, locals = {}, &block) #:nodoc:
def render(options = {}, locals = {}, &block)
case options
when Hash
if block_given?
content = _render_partial(options.merge(:partial => options[:layout]), &block)
safe_concat(content)
elsif options.key?(:partial)
_render_partial(options)
else
_render(options)
template = _determine_template(options)
self.formats = template.formats
_render_template(template, options[:layout], options)
end
when :update
update_page(&block)
......@@ -28,44 +32,18 @@ def render(options = {}, locals = {}, &block) #:nodoc:
end
end
# This is the API to render a ViewContext's template from a controller.
def render_template(options, &block)
_evaluate_assigns_and_ivars
# TODO Layout for partials should be handled here, because inside the
# partial renderer it looks for the layout as a partial.
if options.key?(:partial) && options[:layout]
options[:layout] = _find_layout(options[:layout])
end
_render(options, &block)
end
# This method holds the common render logic for both controllers and
# views rendering stacks.
def _render(options) #:nodoc:
if options.key?(:partial)
_render_partial(options)
else
template = _determine_template(options)
yield template if block_given?
_render_template(template, options[:layout], options)
end
end
# Determine the template to be rendered using the given options.
def _determine_template(options) #:nodoc:
if options.key?(:inline)
handler = Template.handler_class_for_extension(options[:type] || "erb")
Template.new(options[:inline], "inline template", handler, {})
elsif options.key?(:text)
Template::Text.new(options[:text], self.formats.try(:first))
elsif options.key?(:_template)
options[:_template]
Template::Text.new(options[:text], formats.try(:first))
elsif options.key?(:file)
with_fallbacks { find(options[:file], options[:prefix]) }
with_fallbacks { find_template(options[:file], options[:prefix]) }
elsif options.key?(:template)
find(options[:template], options[:prefix])
options[:template].respond_to?(:render) ?
options[:template] : find_template(options[:template], options[:prefix])
end
end
......@@ -73,7 +51,7 @@ def _determine_template(options) #:nodoc:
# supplied as well.
def _render_template(template, layout = nil, options = {}) #:nodoc:
locals = options[:locals] || {}
layout = _find_layout(layout) if layout
layout = find_layout(layout) if layout
ActiveSupport::Notifications.instrument("action_view.render_template",
:identifier => template.identifier, :layout => layout.try(:identifier)) do
......@@ -89,6 +67,5 @@ def _render_template(template, layout = nil, options = {}) #:nodoc:
content
end
end
end
end
......@@ -6,8 +6,7 @@ class RJS < Template::Handler
self.default_format = Mime::JS
def compile(template)
"controller.response.content_type ||= Mime::JS;" +
"update_page do |page|;#{template.source}\nend"
"update_page do |page|;#{template.source}\nend"
end
def default_format
......
module ActionView #:nodoc:
class Template
class Text < String #:nodoc:
def initialize(string, content_type = nil)
attr_accessor :mime_type
def initialize(string, mime_type = nil)
super(string.to_s)
@content_type = Mime[content_type] || content_type if content_type
@content_type ||= Mime::TEXT
@mime_type = Mime[mime_type] || mime_type if mime_type
@mime_type ||= Mime::TEXT
end
def identifier
......@@ -19,12 +21,8 @@ def render(*args)
to_s
end
def mime_type
@content_type
end
def formats
[@content_type.to_sym]
[@mime_type.to_sym]
end
def partial?
......
......@@ -8,210 +8,158 @@ class Base < AbstractController::Base
include AbstractController::Rendering
include AbstractController::Layouts
def _prefix
"template"
end
self.view_paths = [ActionView::FixtureResolver.new(
"abstract_controller_tests/layouts/with_string_implied_child.erb" =>
"With Implied <%= yield %>",
"layouts/hello.erb" => "With String <%= yield %>",
"layouts/hello_override.erb" => "With Override <%= yield %>",
"layouts/overwrite.erb" => "Overwrite <%= yield %>",
"layouts/with_false_layout.erb" => "False Layout <%= yield %>"
"layouts/with_false_layout.erb" => "False Layout <%= yield %>",
"abstract_controller_tests/layouts/with_string_implied_child.erb" =>
"With Implied <%= yield %>"
)]
end
class Blank < Base
self.view_paths = ActionView::FixtureResolver.new("template/index.erb" => "Hello blank!")
self.view_paths = []
def index
render
render :template => ActionView::Template::Text.new("Hello blank!")
end
end
class WithString < Base
layout "hello"
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello string!",
"template/overwrite_default.erb" => "Hello string!",
"template/overwrite_false.erb" => "Hello string!",
"template/overwrite_string.erb" => "Hello string!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello string!")
end
def overwrite_default
render :layout => :default
render :template => ActionView::Template::Text.new("Hello string!"), :layout => :default
end
def overwrite_false
render :layout => false
render :template => ActionView::Template::Text.new("Hello string!"), :layout => false
end
def overwrite_string
render :layout => "overwrite"
render :template => ActionView::Template::Text.new("Hello string!"), :layout => "overwrite"
end
def overwrite_skip
render :text => "Hello text!"
end
end
class WithStringChild < WithString
end
class WithStringOverriddenChild < WithString
layout "hello_override"
end
class WithNilChild < WithString
layout nil
end
end
class WithStringImpliedChild < WithString
end
class WithChildOfImplied < WithStringImpliedChild
end
class WithProc < Base
layout proc { |c| "overwrite" }
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello proc!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello proc!")
end
end
class WithSymbol < Base
layout :hello
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello symbol!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello symbol!")
end
private
def hello
"overwrite"
end
end
class WithSymbolReturningString < Base
layout :no_hello
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello missing symbol!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello missing symbol!")
end
private
def no_hello
nil
end
end
class WithSymbolReturningNil < Base
layout :nilz
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello nilz!"
)
def index
render
end
def nilz
render :template => ActionView::Template::Text.new("Hello nilz!")
end
def nilz() end
end
class WithSymbolReturningObj < Base
layout :objekt
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello object!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello nilz!")
end
def objekt
Object.new
end
end
end
class WithSymbolAndNoMethod < Base
layout :no_method
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello boom!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello boom!")
end
end
class WithMissingLayout < Base
layout "missing"
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello missing!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello missing!")
end
end
class WithFalseLayout < Base
layout false
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello false!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello false!")
end
end
class WithNilLayout < Base
layout nil
append_view_path ActionView::FixtureResolver.new(
"template/index.erb" => "Hello nil!"
)
def index
render
render :template => ActionView::Template::Text.new("Hello nil!")
end
end
class TestBase < ActiveSupport::TestCase
test "when no layout is specified, and no default is available, render without a layout" do
controller = Blank.new
controller.process(:index)
assert_equal "Hello blank!", controller.response_body
end
test "when layout is specified as a string, render with that layout" do
controller = WithString.new
controller.process(:index)
......@@ -245,13 +193,13 @@ class TestBase < ActiveSupport::TestCase
test "when layout is specified as a string, but the layout is missing, raise an exception" do
assert_raises(ActionView::MissingTemplate) { WithMissingLayout.new.process(:index) }
end
test "when layout is specified as false, do not use a layout" do
controller = WithFalseLayout.new
controller.process(:index)
assert_equal "Hello false!", controller.response_body
end
test "when layout is specified as nil, do not use a layout" do
controller = WithNilLayout.new
controller.process(:index)
......@@ -263,58 +211,58 @@ class TestBase < ActiveSupport::TestCase
controller.process(:index)
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 "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
controller = WithSymbolReturningNil.new
controller.process(:index)
assert_equal "Hello nilz!", controller.response_body
end
test "when the layout is specified as a symbol and the method doesn't exist, raise an exception" do
assert_raises(NoMethodError) { WithSymbolAndNoMethod.new.process(:index) }
end
test "when the layout is specified as a symbol and the method returns something besides a string/false/nil, raise an exception" do
assert_raises(ArgumentError) { WithSymbolReturningObj.new.process(:index) }
end
test "when a child controller does not have a layout, use the parent controller layout" do
controller = WithStringChild.new
controller.process(:index)
assert_equal "With String Hello string!", controller.response_body
end
test "when a child controller has specified a layout, use that layout and not the parent controller layout" do
controller = WithStringOverriddenChild.new
controller.process(:index)
assert_equal "With Override Hello string!", controller.response_body
end
test "when a child controller has an implied layout, use that layout and not the parent controller layout" do
controller = WithStringImpliedChild.new
controller.process(:index)
assert_equal "With Implied Hello string!", controller.response_body
end
test "when a child controller specifies layout nil, do not use the parent layout" do
controller = WithNilChild.new
controller.process(:index)
assert_equal "Hello string!", controller.response_body
end
test "when a grandchild has no layout specified, the child has an implied layout, and the " \
"parent has specified a layout, use the child controller layout" do
controller = WithChildOfImplied.new
controller.process(:index)
assert_equal "With Implied Hello string!", controller.response_body
end
test "raises an exception when specifying layout true" do
assert_raises ArgumentError do
Object.class_eval do
......@@ -326,4 +274,4 @@ class ::BadFailLayout < AbstractControllerTests::Layouts::Base
end
end
end
end
end
\ No newline at end of file
......@@ -634,6 +634,19 @@ def test_fragment_for
assert_equal 'generated till now -> fragment content', buffer
end
def test_html_safety
assert_nil @store.read('views/name')
content = 'value'.html_safe
assert_equal content, @controller.write_fragment('name', content)
cached = @store.read('views/name')
assert_equal content, cached
assert_equal String, cached.class
html_safe = @controller.read_fragment('name')
assert_equal content, html_safe
assert html_safe.html_safe?
end
end
class FunctionalCachingController < CachingController
......
......@@ -617,6 +617,15 @@ def rescue_action(e)
raise
end
before_filter :only => :render_with_filters do
request.format = :xml
end
# Ensure that the before filter is executed *before* self.formats is set.
def render_with_filters
render :action => :formatted_xml_erb
end
private
def determine_layout
......@@ -1034,6 +1043,11 @@ def test_render_with_explicit_string_template
assert_equal "<html>Hello world!</html>", @response.body
end
def test_render_with_filters
get :render_with_filters
assert_equal "<test>passed formatted xml erb</test>", @response.body
end
# :ported:
def test_double_render
assert_raise(ActionController::DoubleRenderError) { get :double_render }
......
......@@ -16,6 +16,7 @@ class AccountsController < ResourcesController; end
class AdminController < ResourcesController; end
class ProductsController < ResourcesController; end
class ImagesController < ResourcesController; end
class PreferencesController < ResourcesController; end
module Backoffice
class ProductsController < ResourcesController; end
......@@ -1125,6 +1126,12 @@ def test_default_singleton_restful_route_uses_get
end
end
def test_singleton_resource_name_is_not_singularized
with_singleton_resources(:preferences) do
assert_singleton_restful_for :preferences
end
end
protected
def with_restful_routing(*args)
with_routing do |set|
......
......@@ -50,7 +50,7 @@ def host_with_port() 'localhost' end
end
def teardown
ActionController::Base.perform_caching = false
config.perform_caching = false
ENV.delete('RAILS_ASSET_ID')
end
......@@ -141,7 +141,6 @@ def teardown
ImageLinkToTag = {
%(image_tag("xml.png")) => %(<img alt="Xml" src="/images/xml.png" />),
%(image_tag("..jpg")) => %(<img alt="..jpg" src="/images/..jpg" />),
%(image_tag("rss.gif", :alt => "rss syndication")) => %(<img alt="rss syndication" src="/images/rss.gif" />),
%(image_tag("gold.png", :size => "45x70")) => %(<img alt="Gold" height="70" src="/images/gold.png" width="45" />),
%(image_tag("gold.png", "size" => "45x70")) => %(<img alt="Gold" height="70" src="/images/gold.png" width="45" />),
......@@ -422,7 +421,7 @@ def test_caching_image_path_with_caching_and_proc_asset_host_using_request
def test_caching_javascript_include_tag_when_caching_on
ENV["RAILS_ASSET_ID"] = ""
@controller.config.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_dom_equal(
%(<script src="http://a0.example.com/javascripts/all.js" type="text/javascript"></script>),
......@@ -454,7 +453,7 @@ def test_caching_javascript_include_tag_when_caching_on
def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host
ENV['RAILS_ASSET_ID'] = ''
@controller.config.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" }
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_equal '/javascripts/scripts.js'.length, 23
assert_dom_equal(
......@@ -477,7 +476,7 @@ def test_caching_javascript_include_tag_when_caching_on_with_2_argument_proc_ass
"#{request.protocol}assets#{source.length}.example.com"
end
}
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_equal '/javascripts/vanilla.js'.length, 23
assert_dom_equal(
......@@ -517,7 +516,7 @@ def call(source, request)
end
end.new
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_equal '/javascripts/vanilla.js'.length, 23
assert_dom_equal(
......@@ -548,7 +547,7 @@ def ssl?() true end
def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory
ENV["RAILS_ASSET_ID"] = ""
@controller.config.asset_host = 'http://a%d.example.com'
ActionController::Base.perform_caching = true
config.perform_caching = true
hash = '/javascripts/cache/money.js'.hash % 4
assert_dom_equal(
......@@ -564,7 +563,7 @@ def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory
def test_caching_javascript_include_tag_with_all_and_recursive_puts_defaults_at_the_start_of_the_file
ENV["RAILS_ASSET_ID"] = ""
@controller.config.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_dom_equal(
%(<script src="http://a0.example.com/javascripts/combined.js" type="text/javascript"></script>),
......@@ -585,7 +584,7 @@ def test_caching_javascript_include_tag_with_all_and_recursive_puts_defaults_at_
def test_caching_javascript_include_tag_with_all_puts_defaults_at_the_start_of_the_file
ENV["RAILS_ASSET_ID"] = ""
@controller.config.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_dom_equal(
%(<script src="http://a0.example.com/javascripts/combined.js" type="text/javascript"></script>),
......@@ -606,7 +605,7 @@ def test_caching_javascript_include_tag_with_all_puts_defaults_at_the_start_of_t
def test_caching_javascript_include_tag_with_relative_url_root
ENV["RAILS_ASSET_ID"] = ""
@controller.config.relative_url_root = "/collaboration/hieraki"
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_dom_equal(
%(<script src="/collaboration/hieraki/javascripts/all.js" type="text/javascript"></script>),
......@@ -629,7 +628,7 @@ def test_caching_javascript_include_tag_with_relative_url_root
def test_caching_javascript_include_tag_when_caching_off
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.perform_caching = false
config.perform_caching = false
assert_dom_equal(
%(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
......@@ -658,7 +657,7 @@ def test_caching_javascript_include_tag_when_caching_off
def test_caching_javascript_include_tag_when_caching_on_and_missing_javascript_file
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_raise(Errno::ENOENT) {
javascript_include_tag('bank', 'robber', 'missing_security_guard', :cache => true)
......@@ -675,7 +674,7 @@ def test_caching_javascript_include_tag_when_caching_on_and_missing_javascript_f
def test_caching_javascript_include_tag_when_caching_off_and_missing_javascript_file
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.perform_caching = false
config.perform_caching = false
assert_raise(Errno::ENOENT) {
javascript_include_tag('bank', 'robber', 'missing_security_guard', :cache => true)
......@@ -693,7 +692,7 @@ def test_caching_javascript_include_tag_when_caching_off_and_missing_javascript_
def test_caching_stylesheet_link_tag_when_caching_on
ENV["RAILS_ASSET_ID"] = ""
@controller.config.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_dom_equal(
%(<link href="http://a0.example.com/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" />),
......@@ -760,7 +759,7 @@ def test_concat_stylesheet_link_tag_when_caching_off
def test_caching_stylesheet_link_tag_when_caching_on_and_missing_css_file
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_raise(Errno::ENOENT) {
stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => true)
......@@ -781,7 +780,7 @@ def test_caching_stylesheet_link_tag_when_caching_on_and_missing_css_file
def test_caching_stylesheet_link_tag_when_caching_off_and_missing_css_file
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.perform_caching = false
config.perform_caching = false
assert_raise(Errno::ENOENT) {
stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => true)
......@@ -803,7 +802,7 @@ def test_caching_stylesheet_link_tag_when_caching_off_and_missing_css_file
def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host
ENV["RAILS_ASSET_ID"] = ""
@controller.config.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" }
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_equal '/stylesheets/styles.css'.length, 23
assert_dom_equal(
......@@ -820,7 +819,7 @@ def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host
def test_caching_stylesheet_link_tag_with_relative_url_root
ENV["RAILS_ASSET_ID"] = ""
@controller.config.relative_url_root = "/collaboration/hieraki"
ActionController::Base.perform_caching = true
config.perform_caching = true
assert_dom_equal(
%(<link href="/collaboration/hieraki/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" />),
......@@ -845,7 +844,7 @@ def test_caching_stylesheet_link_tag_with_relative_url_root
def test_caching_stylesheet_include_tag_when_caching_off
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.perform_caching = false
config.perform_caching = false
assert_dom_equal(
%(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" type="text/css" />),
......
......@@ -12,4 +12,10 @@ def test_content_for
assert content_for?(:title)
assert ! content_for?(:something_else)
end
def test_with_output_buffer_does_not_assume_there_is_an_output_buffer
av = ActionView::Base.new
assert_nil av.output_buffer
assert_equal "", av.with_output_buffer {}
end
end
......@@ -111,8 +111,11 @@ def clear_association_cache #:nodoc:
private
# Gets the specified association instance if it responds to :loaded?, nil otherwise.
def association_instance_get(name)
association = instance_variable_get("@#{name}")
association if association.respond_to?(:loaded?)
ivar = "@#{name}"
if instance_variable_defined?(ivar)
association = instance_variable_get(ivar)
association if association.respond_to?(:loaded?)
end
end
# Set the specified association instance.
......
......@@ -101,6 +101,7 @@ def to_ary
Array(@target)
end
end
alias_method :to_a, :to_ary
def reset
reset_target!
......
......@@ -49,7 +49,7 @@ class AssociationProxy #:nodoc:
alias_method :proxy_respond_to?, :respond_to?
alias_method :proxy_extend, :extend
delegate :to_param, :to => :proxy_target
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
instance_methods.each { |m| undef_method m unless m =~ /^(?:nil\?|send|object_id|to_a)$|^__|proxy_/ }
def initialize(owner, reflection)
@owner, @reflection = owner, reflection
......
......@@ -1041,6 +1041,10 @@ def instantiate(record)
object.instance_variable_set(:'@attributes', record)
object.instance_variable_set(:'@attributes_cache', {})
object.instance_variable_set(:@new_record, false)
object.instance_variable_set(:@readonly, false)
object.instance_variable_set(:@destroyed, false)
object.instance_variable_set(:@marked_for_destruction, false)
object.send(:_run_find_callbacks)
object.send(:_run_initialize_callbacks)
......@@ -1506,6 +1510,10 @@ def initialize(attributes = nil)
@attributes = attributes_from_column_definition
@attributes_cache = {}
@new_record = true
@readonly = false
@destroyed = false
@marked_for_destruction = false
ensure_proper_type
if scope = self.class.send(:current_scoped_methods)
......@@ -1570,7 +1578,7 @@ def initialize_copy(other)
# user_path(user) # => "/users/Phusion"
def to_param
# We can't use alias_method here, because method 'id' optimizes itself on the fly.
(id = self.id) ? id.to_s : nil # Be sure to stringify the id for routes
id && id.to_s # Be sure to stringify the id for routes
end
# Returns a cache key that can be used to identify this record.
......@@ -1597,12 +1605,12 @@ def quoted_id #:nodoc:
# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false.
def new_record?
@new_record || false
@new_record
end
# Returns true if this object has been destroyed, otherwise returns false.
def destroyed?
@destroyed || false
@destroyed
end
# Returns if the record is persisted, i.e. it's not a new record and it was not destroyed.
......@@ -1695,7 +1703,7 @@ def becomes(klass)
# This is especially useful for boolean flags on existing records. The regular +update_attribute+ method
# in Base is replaced with this when the validations module is mixed in, which it is by default.
def update_attribute(name, value)
send(name.to_s + '=', value)
send("#{name}=", value)
save(:validate => false)
end
......@@ -1912,14 +1920,14 @@ def frozen?
# Returns duplicated record with unfreezed attributes.
def dup
obj = super
obj.instance_variable_set('@attributes', instance_variable_get('@attributes').dup)
obj.instance_variable_set('@attributes', @attributes.dup)
obj
end
# Returns +true+ if the record is read only. Records loaded through joins with piggy-back
# attributes will be marked as read only since they cannot be saved.
def readonly?
defined?(@readonly) && @readonly == true
@readonly
end
# Marks this record as read only.
......@@ -1939,10 +1947,10 @@ def inspect
protected
def clone_attributes(reader_method = :read_attribute, attributes = {})
self.attribute_names.inject(attributes) do |attrs, name|
attrs[name] = clone_attribute_value(reader_method, name)
attrs
attribute_names.each do |name|
attributes[name] = clone_attribute_value(reader_method, name)
end
attributes
end
def clone_attribute_value(reader_method, attribute_name)
......@@ -2245,4 +2253,4 @@ def object_from_yaml(string)
# TODO: Remove this and make it work with LAZY flag
require 'active_record/connection_adapters/abstract_adapter'
ActiveRecord.run_base_hooks(ActiveRecord::Base)
\ No newline at end of file
ActiveRecord.run_base_hooks(ActiveRecord::Base)
......@@ -7,6 +7,9 @@ def self.match(method)
def initialize(method)
@finder = :first
@bang = false
@instantiator = nil
case method.to_s
when /^find_(all_by|last_by|by)_([_a-zA-Z]\w*)$/
@finder = :last if $1 == 'last_by'
......
......@@ -315,7 +315,9 @@ def write(text="")
end
def announce(message)
text = "#{@version} #{name}: #{message}"
version = defined?(@version) ? @version : nil
text = "#{version} #{name}: #{message}"
length = [0, 75 - text.length].max
write "== %s %s" % [text, "=" * length]
end
......
......@@ -154,6 +154,11 @@ def klass
@klass ||= active_record.send(:compute_type, class_name)
end
def initialize(macro, name, options, active_record)
super
@collection = [:has_many, :has_and_belongs_to_many].include?(macro)
end
# Returns a new, unsaved instance of the associated class. +options+ will
# be passed to the class's constructor.
def build_association(*options)
......@@ -256,9 +261,6 @@ def polymorphic_inverse_of(associated_class)
# association. Returns +true+ if the +macro+ is one of +has_many+ or
# +has_and_belongs_to_many+, +false+ otherwise.
def collection?
if @collection.nil?
@collection = [:has_many, :has_and_belongs_to_many].include?(macro)
end
@collection
end
......
......@@ -14,6 +14,14 @@ class Relation
def initialize(klass, table)
@klass, @table = klass, table
@readonly_value = nil
@create_with_value = nil
@implicit_readonly = nil
@limit_value = nil
@offset_value = nil
@loaded = nil
(ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])}
end
......
......@@ -18,10 +18,14 @@
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
fixtures :posts, :readers, :people, :comments, :authors, :owners, :pets, :toys, :jobs, :references, :companies
def test_associate_existing
assert_queries(2) { posts(:thinking);people(:david) }
# Dummies to force column loads so query counts are clean.
def setup
Person.create :first_name => 'gummy'
Reader.create :person_id => 0, :post_id => 0
end
posts(:thinking).people
def test_associate_existing
assert_queries(2) { posts(:thinking); people(:david) }
assert_queries(1) do
posts(:thinking).people << people(:david)
......
......@@ -180,6 +180,14 @@ def test_reload_returns_assocition
end
end
if RUBY_VERSION < '1.9'
def test_splat_does_not_invoke_to_a_on_singular_targets
author = posts(:welcome).author
author.reload.target.expects(:to_a).never
[*author]
end
end
def setup_dangling_association
josh = Author.create(:name => "Josh")
p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
......
......@@ -7,6 +7,7 @@
require 'test/unit'
require 'stringio'
require 'mocha'
require 'active_record'
require 'active_support/dependencies'
......
......@@ -89,12 +89,8 @@ def to_s
self
end
def as_str
''.replace(self)
end
def to_yaml(*args)
as_str.to_yaml(*args)
to_str.to_yaml(*args)
end
end
end
......
......@@ -27,7 +27,7 @@ def rake(*tasks)
puts
puts "[CruiseControl] Bundling RubyGems"
puts
build_results[:bundle] = system 'rm -rf ~/.bundle; env CI=1 bundle install'
build_results[:bundle] = system 'sudo rm -rf ~/.bundle; env CI=1 bundle install'
end
cd "#{root_dir}/activesupport" do
......
......@@ -178,7 +178,8 @@ def apply_rails_template
end
def bundle_if_dev_or_edge
run "bundle install" if dev_or_edge?
bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
run "#{bundle_command} install" if dev_or_edge?
end
protected
......@@ -220,6 +221,8 @@ def valid_app_const?
raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
elsif RESERVED_NAMES.include?(app_name)
raise Error, "Invalid application name #{app_name}. Please give a name which does not match one of the reserved rails words."
elsif Object.const_defined?(app_const_base)
raise Error, "Invalid application name #{app_name}, constant #{app_const_base} is already in use. Please choose another application name."
end
end
......
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
ENV_PATH = File.expand_path('../../config/environment', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
ENV_PATH = File.expand_path('../../config/environment', __FILE__)
BOOT_PATH = File.expand_path('../../config/boot', __FILE__)
APP_PATH = File.expand_path('../../config/application', __FILE__)
require BOOT_PATH
require 'rails/commands'
......@@ -34,13 +34,15 @@
Rails::Console.start(Rails::Application)
when 's', 'server'
require 'rails/commands/server'
# Initialize the server first, so environment options are set
server = Rails::Server.new
require ENV_PATH
require APP_PATH
Dir.chdir(Rails::Application.root)
server.start
when 'db', 'dbconsole'
require 'rails/commands/dbconsole'
require ENV_PATH
require APP_PATH
Rails::DBConsole.start(Rails::Application)
when 'application'
......@@ -55,7 +57,7 @@
require ENV_PATH
require 'rails/commands/performance/profiler'
when 'plugin'
require ENV_PATH
require APP_PATH
require 'rails/commands/plugin'
when 'runner'
require 'rails/commands/runner'
......
......@@ -202,6 +202,10 @@ def self.help(command = 'generate')
rails.delete("app")
print_list("rails", rails)
groups.delete("active_record") if options[:rails][:orm] == :active_record
groups.delete("test_unit") if options[:rails][:test_framework] == :test_unit
groups.delete("erb") if options[:rails][:template_engine] == :erb
groups.sort.each { |b, n| print_list(b, n) }
end
......
......@@ -9,6 +9,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def setup
super
Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
@bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
end
def teardown
......@@ -65,6 +66,13 @@ def test_invalid_application_name_raises_an_error
assert_equal "Invalid application name 43-things. Please give a name which does not start with numbers.\n", content
end
def test_application_name_raises_an_error_if_name_already_used_constant
%w{ String Hash Class Module Set Symbol }.each do |ruby_class|
content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] }
assert_equal "Invalid application name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another application name.\n", content
end
end
def test_invalid_application_name_is_fixed
run_generator [File.join(destination_root, "things-43")]
assert_file "things-43/config/environment.rb", /Things43::Application\.initialize!/
......@@ -161,14 +169,14 @@ def test_file_is_added_for_backwards_compatibility
end
def test_dev_option
generator([destination_root], :dev => true).expects(:run).with("bundle install")
generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install")
silence(:stdout){ generator.invoke }
rails_path = File.expand_path('../../..', Rails.root)
assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/
end
def test_edge_option
generator([destination_root], :edge => true).expects(:run).with("bundle install")
generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install")
silence(:stdout){ generator.invoke }
assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$/
end
......
......@@ -104,11 +104,25 @@ def test_rails_generators_help_with_builtin_information
def test_rails_generators_with_others_information
output = capture(:stdout){ Rails::Generators.help }
assert_match /ActiveRecord:/, output
assert_match /Fixjour:/, output
assert_match /^ fixjour$/, output
end
def test_rails_generators_does_not_show_activerecord_info_if_its_the_default
output = capture(:stdout){ Rails::Generators.help }
assert_no_match /ActiveRecord:/, output
assert_no_match /^ active_record:model$/, output
assert_no_match /^ active_record:fixjour$/, output
end
def test_rails_generators_shows_activerecord_info_if_its_not_the_default
Rails::Generators.options[:rails][:orm] = :data_mapper
output = capture(:stdout){ Rails::Generators.help }
assert_match /ActiveRecord:/, output
assert_match /^ active_record:model$/, output
assert_match /^ active_record:fixjour$/, output
assert_match /^ fixjour$/, output
ensure
Rails::Generators.options[:rails][:orm] = :active_record
end
def test_no_color_sets_proper_shell
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册