mirror of
https://github.com/github/rails.git
synced 2026-01-29 00:08:15 -05:00
Merge branch 'master' of git@github.com:rails/rails
This commit is contained in:
@@ -530,7 +530,7 @@ module ActionMailer #:nodoc:
|
||||
end
|
||||
|
||||
def render_message(method_name, body)
|
||||
render :file => method_name, :body => body
|
||||
render :file => method_name, :body => body, :use_full_path => true
|
||||
end
|
||||
|
||||
def render(opts)
|
||||
@@ -538,6 +538,7 @@ module ActionMailer #:nodoc:
|
||||
if opts[:file] && opts[:file] !~ /\//
|
||||
opts[:file] = "#{mailer_name}/#{opts[:file]}"
|
||||
end
|
||||
opts[:use_full_path] = true
|
||||
initialize_template_class(body).render(opts)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
*Edge*
|
||||
|
||||
* Make caching more aware of mime types. Ensure request format is not considered while expiring cache. [Jonathan del Strother]
|
||||
|
||||
* Drop ActionController::Base.allow_concurrency flag [Josh Peek]
|
||||
|
||||
* More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper]
|
||||
|
||||
* Added page.reload functionality. Resolves #277. [Sean Huber]
|
||||
|
||||
* Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn't match (not just if they're both present) [Mark Imbriaco, Bradford Folkens]
|
||||
|
||||
@@ -283,13 +283,6 @@ module ActionController #:nodoc:
|
||||
@@debug_routes = true
|
||||
cattr_accessor :debug_routes
|
||||
|
||||
# Indicates to Mongrel or Webrick whether to allow concurrent action
|
||||
# processing. Your controller actions and any other code they call must
|
||||
# also behave well when called from concurrent threads. Turned off by
|
||||
# default.
|
||||
@@allow_concurrency = false
|
||||
cattr_accessor :allow_concurrency
|
||||
|
||||
# Modern REST web services often need to submit complex data to the web application.
|
||||
# The <tt>@@param_parsers</tt> hash lets you register handlers which will process the HTTP body and add parameters to the
|
||||
# <tt>params</tt> hash. These handlers are invoked for POST and PUT requests.
|
||||
|
||||
@@ -67,10 +67,10 @@ module ActionController #:nodoc:
|
||||
|
||||
if options[:action].is_a?(Array)
|
||||
options[:action].dup.each do |action|
|
||||
expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action })))
|
||||
expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }), false))
|
||||
end
|
||||
else
|
||||
expire_fragment(ActionCachePath.path_for(self, options))
|
||||
expire_fragment(ActionCachePath.path_for(self, options, false))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -125,16 +125,24 @@ module ActionController #:nodoc:
|
||||
attr_reader :path, :extension
|
||||
|
||||
class << self
|
||||
def path_for(controller, options)
|
||||
new(controller, options).path
|
||||
def path_for(controller, options, infer_extension=true)
|
||||
new(controller, options, infer_extension).path
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(controller, options = {})
|
||||
@extension = extract_extension(controller.request.path)
|
||||
|
||||
# When true, infer_extension will look up the cache path extension from the request's path & format.
|
||||
# This is desirable when reading and writing the cache, but not when expiring the cache - expire_action should expire the same files regardless of the request format.
|
||||
def initialize(controller, options = {}, infer_extension=true)
|
||||
if infer_extension and options.is_a? Hash
|
||||
request_extension = extract_extension(controller.request)
|
||||
options = options.reverse_merge(:format => request_extension)
|
||||
end
|
||||
path = controller.url_for(options).split('://').last
|
||||
normalize!(path)
|
||||
add_extension!(path, @extension)
|
||||
if infer_extension
|
||||
@extension = request_extension
|
||||
add_extension!(path, @extension)
|
||||
end
|
||||
@path = URI.unescape(path)
|
||||
end
|
||||
|
||||
@@ -144,13 +152,22 @@ module ActionController #:nodoc:
|
||||
end
|
||||
|
||||
def add_extension!(path, extension)
|
||||
path << ".#{extension}" if extension
|
||||
path << ".#{extension}" if extension and !path.ends_with?(extension)
|
||||
end
|
||||
|
||||
def extract_extension(file_path)
|
||||
|
||||
def extract_extension(request)
|
||||
# Don't want just what comes after the last '.' to accommodate multi part extensions
|
||||
# such as tar.gz.
|
||||
file_path[/^[^.]+\.(.+)$/, 1]
|
||||
extension = request.path[/^[^.]+\.(.+)$/, 1]
|
||||
|
||||
# If there's no extension in the path, check request.format
|
||||
if extension.nil?
|
||||
extension = request.format.to_sym.to_s
|
||||
if extension=='all'
|
||||
extension = nil
|
||||
end
|
||||
end
|
||||
extension
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -189,6 +189,8 @@ end_msg
|
||||
if @body.respond_to?(:call)
|
||||
@writer = lambda { |x| callback.call(x) }
|
||||
@body.call(self, self)
|
||||
elsif @body.is_a?(String)
|
||||
@body.each_line(&callback)
|
||||
else
|
||||
@body.each(&callback)
|
||||
end
|
||||
|
||||
@@ -31,18 +31,21 @@ module ActionController
|
||||
module RecordIdentifier
|
||||
extend self
|
||||
|
||||
JOIN = '_'.freeze
|
||||
NEW = 'new'.freeze
|
||||
|
||||
# Returns plural/singular for a record or class. Example:
|
||||
#
|
||||
# partial_path(post) # => "posts/post"
|
||||
# partial_path(Person) # => "people/person"
|
||||
# partial_path(Person, "admin/games") # => "admin/people/person"
|
||||
def partial_path(record_or_class, controller_path = nil)
|
||||
klass = class_from_record_or_class(record_or_class)
|
||||
name = model_name_from_record_or_class(record_or_class)
|
||||
|
||||
if controller_path && controller_path.include?("/")
|
||||
"#{File.dirname(controller_path)}/#{klass.name.tableize}/#{klass.name.demodulize.underscore}"
|
||||
"#{File.dirname(controller_path)}/#{name.partial_path}"
|
||||
else
|
||||
"#{klass.name.tableize}/#{klass.name.demodulize.underscore}"
|
||||
name.partial_path
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,7 +59,8 @@ module ActionController
|
||||
# dom_class(post, :edit) # => "edit_post"
|
||||
# dom_class(Person, :edit) # => "edit_person"
|
||||
def dom_class(record_or_class, prefix = nil)
|
||||
[ prefix, singular_class_name(record_or_class) ].compact * '_'
|
||||
singular = singular_class_name(record_or_class)
|
||||
prefix ? "#{prefix}#{JOIN}#{singular}" : singular
|
||||
end
|
||||
|
||||
# The DOM id convention is to use the singular form of an object or class with the id following an underscore.
|
||||
@@ -69,8 +73,11 @@ module ActionController
|
||||
#
|
||||
# dom_id(Post.new(:id => 45), :edit) # => "edit_post_45"
|
||||
def dom_id(record, prefix = nil)
|
||||
prefix ||= 'new' unless record.id
|
||||
[ prefix, singular_class_name(record), record.id ].compact * '_'
|
||||
if record_id = record.id
|
||||
"#{dom_class(record, prefix)}#{JOIN}#{record_id}"
|
||||
else
|
||||
dom_class(record, prefix || NEW)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the plural class name of a record or class. Examples:
|
||||
@@ -78,7 +85,7 @@ module ActionController
|
||||
# plural_class_name(post) # => "posts"
|
||||
# plural_class_name(Highrise::Person) # => "highrise_people"
|
||||
def plural_class_name(record_or_class)
|
||||
singular_class_name(record_or_class).pluralize
|
||||
model_name_from_record_or_class(record_or_class).plural
|
||||
end
|
||||
|
||||
# Returns the singular class name of a record or class. Examples:
|
||||
@@ -86,12 +93,12 @@ module ActionController
|
||||
# singular_class_name(post) # => "post"
|
||||
# singular_class_name(Highrise::Person) # => "highrise_person"
|
||||
def singular_class_name(record_or_class)
|
||||
class_from_record_or_class(record_or_class).name.underscore.tr('/', '_')
|
||||
model_name_from_record_or_class(record_or_class).singular
|
||||
end
|
||||
|
||||
private
|
||||
def class_from_record_or_class(record_or_class)
|
||||
record_or_class.is_a?(Class) ? record_or_class : record_or_class.class
|
||||
def model_name_from_record_or_class(record_or_class)
|
||||
(record_or_class.is_a?(Class) ? record_or_class : record_or_class.class).model_name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -249,7 +249,7 @@ module ActionController
|
||||
end
|
||||
|
||||
def extract_value
|
||||
"#{local_name} = hash[:#{key}] && hash[:#{key}].collect { |path_component| URI.escape(path_component.to_param, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}"
|
||||
"#{local_name} = hash[:#{key}] && Array(hash[:#{key}]).collect { |path_component| URI.escape(path_component.to_param, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}"
|
||||
end
|
||||
|
||||
def default
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
require 'action_controller/session/cookie_store'
|
||||
require 'action_controller/session/drb_store'
|
||||
require 'action_controller/session/mem_cache_store'
|
||||
if Object.const_defined?(:ActiveRecord)
|
||||
require 'action_controller/session/active_record_store'
|
||||
end
|
||||
|
||||
module ActionController #:nodoc:
|
||||
module SessionManagement #:nodoc:
|
||||
def self.included(base)
|
||||
@@ -22,6 +15,8 @@ module ActionController #:nodoc:
|
||||
# <tt>:p_store</tt>, <tt>:drb_store</tt>, <tt>:mem_cache_store</tt>, or
|
||||
# <tt>:memory_store</tt>) or your own custom class.
|
||||
def session_store=(store)
|
||||
require "action_controller/session/#{store.to_s}" if [:active_record_store, :drb_store, :mem_cache_store].include?(store)
|
||||
|
||||
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:database_manager] =
|
||||
store.is_a?(Symbol) ? CGI::Session.const_get(store == :drb_store ? "DRbStore" : store.to_s.camelize) : store
|
||||
end
|
||||
|
||||
@@ -21,12 +21,7 @@
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
|
||||
require 'action_view/template_handler'
|
||||
require 'action_view/template_handlers/compilable'
|
||||
require 'action_view/template_handlers/builder'
|
||||
require 'action_view/template_handlers/erb'
|
||||
require 'action_view/template_handlers/rjs'
|
||||
|
||||
require 'action_view/template_handlers'
|
||||
require 'action_view/template_finder'
|
||||
require 'action_view/template'
|
||||
require 'action_view/partial_template'
|
||||
|
||||
@@ -156,10 +156,12 @@ module ActionView #:nodoc:
|
||||
attr_reader :finder
|
||||
attr_accessor :base_path, :assigns, :template_extension, :first_render
|
||||
attr_accessor :controller
|
||||
|
||||
|
||||
attr_writer :template_format
|
||||
attr_accessor :current_render_extension
|
||||
|
||||
attr_accessor :output_buffer
|
||||
|
||||
# Specify trim mode for the ERB compiler. Defaults to '-'.
|
||||
# See ERb documentation for suitable values.
|
||||
@@erb_trim_mode = '-'
|
||||
@@ -178,14 +180,11 @@ module ActionView #:nodoc:
|
||||
# that alert()s the caught exception (and then re-raises it).
|
||||
@@debug_rjs = false
|
||||
cattr_accessor :debug_rjs
|
||||
|
||||
@@erb_variable = '_erbout'
|
||||
cattr_accessor :erb_variable
|
||||
|
||||
|
||||
attr_internal :request
|
||||
|
||||
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
|
||||
:flash, :logger, :action_name, :to => :controller
|
||||
:flash, :logger, :action_name, :controller_name, :to => :controller
|
||||
|
||||
module CompiledTemplates #:nodoc:
|
||||
# holds compiled template code
|
||||
@@ -253,12 +252,13 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
||||
elsif options == :update
|
||||
update_page(&block)
|
||||
elsif options.is_a?(Hash)
|
||||
use_full_path = options[:use_full_path]
|
||||
options = options.reverse_merge(:locals => {}, :use_full_path => true)
|
||||
|
||||
if partial_layout = options.delete(:layout)
|
||||
if block_given?
|
||||
wrap_content_for_layout capture(&block) do
|
||||
concat(render(options.merge(:partial => partial_layout)), block.binding)
|
||||
concat(render(options.merge(:partial => partial_layout)))
|
||||
end
|
||||
else
|
||||
wrap_content_for_layout render(options) do
|
||||
@@ -266,7 +266,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
||||
end
|
||||
end
|
||||
elsif options[:file]
|
||||
render_file(options[:file], options[:use_full_path], options[:locals])
|
||||
render_file(options[:file], use_full_path || false, options[:locals])
|
||||
elsif options[:partial] && options[:collection]
|
||||
render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals])
|
||||
elsif options[:partial]
|
||||
@@ -316,9 +316,10 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
||||
|
||||
private
|
||||
def wrap_content_for_layout(content)
|
||||
original_content_for_layout = @content_for_layout
|
||||
@content_for_layout = content
|
||||
returning(yield) { @content_for_layout = original_content_for_layout }
|
||||
original_content_for_layout, @content_for_layout = @content_for_layout, content
|
||||
yield
|
||||
ensure
|
||||
@content_for_layout = original_content_for_layout
|
||||
end
|
||||
|
||||
# Evaluate the local assigns and pushes them to the view.
|
||||
|
||||
@@ -31,20 +31,13 @@ module ActionView
|
||||
# </body></html>
|
||||
#
|
||||
def capture(*args, &block)
|
||||
# execute the block
|
||||
begin
|
||||
buffer = eval(ActionView::Base.erb_variable, block.binding)
|
||||
rescue
|
||||
buffer = nil
|
||||
end
|
||||
|
||||
if buffer.nil?
|
||||
capture_block(*args, &block).to_s
|
||||
if output_buffer
|
||||
with_output_buffer { block.call(*args) }
|
||||
else
|
||||
capture_erb_with_buffer(buffer, *args, &block).to_s
|
||||
block.call(*args)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Calling content_for stores a block of markup in an identifier for later use.
|
||||
# You can make subsequent calls to the stored content in other templates or the layout
|
||||
# by passing the identifier as an argument to <tt>yield</tt>.
|
||||
@@ -121,40 +114,18 @@ module ActionView
|
||||
# named <tt>@content_for_#{name_of_the_content_block}</tt>. The preferred usage is now
|
||||
# <tt><%= yield :footer %></tt>.
|
||||
def content_for(name, content = nil, &block)
|
||||
existing_content_for = instance_variable_get("@content_for_#{name}").to_s
|
||||
new_content_for = existing_content_for + (block_given? ? capture(&block) : content)
|
||||
instance_variable_set("@content_for_#{name}", new_content_for)
|
||||
ivar = "@content_for_#{name}"
|
||||
content = capture(&block) if block_given?
|
||||
instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}")
|
||||
end
|
||||
|
||||
private
|
||||
def capture_block(*args, &block)
|
||||
block.call(*args)
|
||||
end
|
||||
|
||||
def capture_erb(*args, &block)
|
||||
buffer = eval(ActionView::Base.erb_variable, block.binding)
|
||||
capture_erb_with_buffer(buffer, *args, &block)
|
||||
end
|
||||
|
||||
def capture_erb_with_buffer(buffer, *args, &block)
|
||||
pos = buffer.length
|
||||
block.call(*args)
|
||||
|
||||
# extract the block
|
||||
data = buffer[pos..-1]
|
||||
|
||||
# replace it in the original with empty string
|
||||
buffer[pos..-1] = ''
|
||||
|
||||
data
|
||||
end
|
||||
|
||||
def erb_content_for(name, &block)
|
||||
eval "@content_for_#{name} = (@content_for_#{name} || '') + capture_erb(&block)"
|
||||
end
|
||||
|
||||
def block_content_for(name, &block)
|
||||
eval "@content_for_#{name} = (@content_for_#{name} || '') + capture_block(&block)"
|
||||
def with_output_buffer(buf = '')
|
||||
self.output_buffer, old_buffer = buf, output_buffer
|
||||
yield
|
||||
output_buffer
|
||||
ensure
|
||||
self.output_buffer = old_buffer
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -249,9 +249,9 @@ module ActionView
|
||||
args.unshift object
|
||||
end
|
||||
|
||||
concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}), proc.binding)
|
||||
concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
|
||||
fields_for(object_name, *(args << options), &proc)
|
||||
concat('</form>', proc.binding)
|
||||
concat('</form>')
|
||||
end
|
||||
|
||||
def apply_form_for_options!(object_or_array, options) #:nodoc:
|
||||
|
||||
@@ -304,7 +304,7 @@ module ActionView
|
||||
#
|
||||
# NOTE: Only the option tags are returned, you have to wrap this call in
|
||||
# a regular HTML select tag.
|
||||
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = TimeZone)
|
||||
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
|
||||
zone_options = ""
|
||||
|
||||
zones = model.all
|
||||
@@ -417,7 +417,7 @@ module ActionView
|
||||
value = value(object)
|
||||
content_tag("select",
|
||||
add_options(
|
||||
time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || TimeZone),
|
||||
time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || ActiveSupport::TimeZone),
|
||||
options, value
|
||||
), html_options
|
||||
)
|
||||
|
||||
@@ -407,10 +407,10 @@ module ActionView
|
||||
# # => <fieldset><legend>Your details</legend><p><input id="name" name="name" type="text" /></p></fieldset>
|
||||
def field_set_tag(legend = nil, &block)
|
||||
content = capture(&block)
|
||||
concat(tag(:fieldset, {}, true), block.binding)
|
||||
concat(content_tag(:legend, legend), block.binding) unless legend.blank?
|
||||
concat(content, block.binding)
|
||||
concat("</fieldset>", block.binding)
|
||||
concat(tag(:fieldset, {}, true))
|
||||
concat(content_tag(:legend, legend)) unless legend.blank?
|
||||
concat(content)
|
||||
concat("</fieldset>")
|
||||
end
|
||||
|
||||
private
|
||||
@@ -442,9 +442,9 @@ module ActionView
|
||||
|
||||
def form_tag_in_block(html_options, &block)
|
||||
content = capture(&block)
|
||||
concat(form_tag_html(html_options), block.binding)
|
||||
concat(content, block.binding)
|
||||
concat("</form>", block.binding)
|
||||
concat(form_tag_html(html_options))
|
||||
concat(content)
|
||||
concat("</form>")
|
||||
end
|
||||
|
||||
def token_tag
|
||||
|
||||
@@ -172,20 +172,17 @@ module ActionView
|
||||
# alert('All is good')
|
||||
# <% end -%>
|
||||
def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
|
||||
if block_given?
|
||||
html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
||||
content = capture(&block)
|
||||
else
|
||||
content = content_or_options_with_block
|
||||
end
|
||||
content =
|
||||
if block_given?
|
||||
html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
||||
capture(&block)
|
||||
else
|
||||
content_or_options_with_block
|
||||
end
|
||||
|
||||
javascript_tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
|
||||
|
||||
if block_given? && block_is_within_action_view?(block)
|
||||
concat(javascript_tag, block.binding)
|
||||
else
|
||||
javascript_tag
|
||||
end
|
||||
tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
|
||||
|
||||
block_given? ? concat(tag) : tag
|
||||
end
|
||||
|
||||
def javascript_cdata_section(content) #:nodoc:
|
||||
@@ -205,11 +202,6 @@ module ActionView
|
||||
end
|
||||
js_option
|
||||
end
|
||||
|
||||
private
|
||||
def block_is_within_action_view?(block)
|
||||
eval("defined? _erbout", block.binding)
|
||||
end
|
||||
end
|
||||
|
||||
JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper
|
||||
|
||||
@@ -382,9 +382,9 @@ module ActionView
|
||||
args.unshift object
|
||||
end
|
||||
|
||||
concat(form_remote_tag(options), proc.binding)
|
||||
concat(form_remote_tag(options))
|
||||
fields_for(object_name, *(args << options), &proc)
|
||||
concat('</form>', proc.binding)
|
||||
concat('</form>')
|
||||
end
|
||||
alias_method :form_remote_for, :remote_form_for
|
||||
|
||||
|
||||
@@ -51,9 +51,8 @@ module ActionView
|
||||
prefix = args.first.is_a?(Hash) ? nil : args.shift
|
||||
options = args.first.is_a?(Hash) ? args.shift : {}
|
||||
concat content_tag(tag_name, capture(&block),
|
||||
options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })),
|
||||
block.binding
|
||||
options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) }))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'cgi'
|
||||
require 'erb'
|
||||
require 'set'
|
||||
|
||||
module ActionView
|
||||
module Helpers #:nodoc:
|
||||
@@ -8,7 +9,8 @@ module ActionView
|
||||
module TagHelper
|
||||
include ERB::Util
|
||||
|
||||
BOOLEAN_ATTRIBUTES = Set.new(%w(disabled readonly multiple))
|
||||
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple).to_set
|
||||
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym))
|
||||
|
||||
# Returns an empty HTML tag of type +name+ which by default is XHTML
|
||||
# compliant. Set +open+ to true to create an open tag compatible
|
||||
@@ -37,7 +39,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 ? ">" : " />")
|
||||
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}"
|
||||
end
|
||||
|
||||
# Returns an HTML block tag of type +name+ surrounding the +content+. Add
|
||||
@@ -66,12 +68,9 @@ module ActionView
|
||||
def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
|
||||
if block_given?
|
||||
options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
||||
content = capture(&block)
|
||||
content_tag = content_tag_string(name, content, options, escape)
|
||||
block_is_within_action_view?(block) ? concat(content_tag, block.binding) : content_tag
|
||||
concat(content_tag_string(name, capture(&block), options, escape))
|
||||
else
|
||||
content = content_or_options_with_block
|
||||
content_tag_string(name, content, options, escape)
|
||||
content_tag_string(name, content_or_options_with_block, options, escape)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -114,7 +113,6 @@ module ActionView
|
||||
if escape
|
||||
options.each do |key, value|
|
||||
next unless value
|
||||
key = key.to_s
|
||||
value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value)
|
||||
attrs << %(#{key}="#{value}")
|
||||
end
|
||||
@@ -124,10 +122,6 @@ module ActionView
|
||||
" #{attrs.sort * ' '}" unless attrs.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def block_is_within_action_view?(block)
|
||||
eval("defined? _erbout", block.binding)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,18 +15,26 @@ module ActionView
|
||||
#
|
||||
# ==== Examples
|
||||
# <%
|
||||
# concat "hello", binding
|
||||
# concat "hello"
|
||||
# # is the equivalent of <%= "hello" %>
|
||||
#
|
||||
# if (logged_in == true):
|
||||
# concat "Logged in!", binding
|
||||
# concat "Logged in!"
|
||||
# else
|
||||
# concat link_to('login', :action => login), binding
|
||||
# concat link_to('login', :action => login)
|
||||
# end
|
||||
# # will either display "Logged in!" or a login link
|
||||
# %>
|
||||
def concat(string, binding)
|
||||
eval(ActionView::Base.erb_variable, binding) << string
|
||||
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.")
|
||||
end
|
||||
|
||||
if output_buffer && string
|
||||
output_buffer << string
|
||||
else
|
||||
string
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_VERSION < '1.9'
|
||||
|
||||
@@ -22,10 +22,10 @@ module ActionView #:nodoc:
|
||||
end
|
||||
|
||||
def render_member(object)
|
||||
@locals[@counter_name] += 1
|
||||
@locals[:object] = @locals[@variable_name] = object
|
||||
|
||||
template = render_template
|
||||
@locals[@counter_name] += 1
|
||||
@locals.delete(@variable_name)
|
||||
@locals.delete(:object)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
module ActionView #:nodoc:
|
||||
class Template #:nodoc:
|
||||
extend TemplateHandlers
|
||||
|
||||
attr_accessor :locals
|
||||
attr_reader :handler, :path, :extension, :filename, :path_without_extension, :method
|
||||
@@ -13,7 +14,7 @@ module ActionView #:nodoc:
|
||||
@view.first_render ||= @path
|
||||
@source = nil # Don't read the source until we know that it is required
|
||||
set_extension_and_file_name(use_full_path)
|
||||
|
||||
|
||||
@locals = locals || {}
|
||||
@handler = self.class.handler_class_for_extension(@extension).new(@view)
|
||||
end
|
||||
@@ -29,7 +30,7 @@ module ActionView #:nodoc:
|
||||
raise TemplateError.new(self, @view.assigns, e)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def render
|
||||
prepare!
|
||||
@handler.render(self)
|
||||
@@ -46,11 +47,11 @@ module ActionView #:nodoc:
|
||||
def base_path_for_exception
|
||||
@finder.find_base_path_for("#{@path_without_extension}.#{@extension}") || @finder.view_paths.first
|
||||
end
|
||||
|
||||
|
||||
def prepare!
|
||||
@view.send :evaluate_assigns
|
||||
@view.current_render_extension = @extension
|
||||
|
||||
|
||||
if @handler.compilable?
|
||||
@handler.compile_template(self) # compile the given template, if necessary
|
||||
@method = @view.method_names[method_key] # Set the method name for this template and run it
|
||||
@@ -58,70 +59,30 @@ module ActionView #:nodoc:
|
||||
end
|
||||
|
||||
private
|
||||
def set_extension_and_file_name(use_full_path)
|
||||
@path_without_extension, @extension = @finder.path_and_extension(@path)
|
||||
if use_full_path
|
||||
if @extension
|
||||
@filename = @finder.pick_template(@path_without_extension, @extension)
|
||||
else
|
||||
@extension = @finder.pick_template_extension(@path).to_s
|
||||
raise_missing_template_exception unless @extension
|
||||
|
||||
def set_extension_and_file_name(use_full_path)
|
||||
@path_without_extension, @extension = @finder.path_and_extension(@path)
|
||||
if use_full_path
|
||||
if @extension
|
||||
@filename = @finder.pick_template(@path_without_extension, @extension)
|
||||
@filename = @finder.pick_template(@path, @extension)
|
||||
@extension = @extension.gsub(/^.+\./, '') # strip off any formats
|
||||
end
|
||||
else
|
||||
@extension = @finder.pick_template_extension(@path).to_s
|
||||
raise_missing_template_exception unless @extension
|
||||
|
||||
@filename = @finder.pick_template(@path, @extension)
|
||||
@extension = @extension.gsub(/^.+\./, '') # strip off any formats
|
||||
@filename = @path
|
||||
end
|
||||
else
|
||||
@filename = @path
|
||||
|
||||
raise_missing_template_exception if @filename.blank?
|
||||
end
|
||||
|
||||
raise_missing_template_exception if @filename.blank?
|
||||
end
|
||||
|
||||
def raise_missing_template_exception
|
||||
full_template_path = @path.include?('.') ? @path : "#{@path}.#{@view.template_format}.erb"
|
||||
display_paths = @finder.view_paths.join(':')
|
||||
template_type = (@path =~ /layouts/i) ? 'layout' : 'template'
|
||||
raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}")
|
||||
end
|
||||
|
||||
# Template Handlers
|
||||
|
||||
@@template_handlers = HashWithIndifferentAccess.new
|
||||
@@default_template_handlers = nil
|
||||
|
||||
# Register a class that knows how to handle template files with the given
|
||||
# extension. This can be used to implement new template types.
|
||||
# The constructor for the class must take the ActiveView::Base instance
|
||||
# as a parameter, and the class must implement a +render+ method that
|
||||
# takes the contents of the template to render as well as the Hash of
|
||||
# local assigns available to the template. The +render+ method ought to
|
||||
# return the rendered template as a string.
|
||||
def self.register_template_handler(extension, klass)
|
||||
@@template_handlers[extension.to_sym] = klass
|
||||
TemplateFinder.update_extension_cache_for(extension.to_s)
|
||||
end
|
||||
|
||||
def self.template_handler_extensions
|
||||
@@template_handlers.keys.map(&:to_s).sort
|
||||
end
|
||||
|
||||
def self.register_default_template_handler(extension, klass)
|
||||
register_template_handler(extension, klass)
|
||||
@@default_template_handlers = klass
|
||||
end
|
||||
|
||||
def self.handler_class_for_extension(extension)
|
||||
(extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
|
||||
end
|
||||
|
||||
register_default_template_handler :erb, TemplateHandlers::ERB
|
||||
register_template_handler :rjs, TemplateHandlers::RJS
|
||||
register_template_handler :builder, TemplateHandlers::Builder
|
||||
|
||||
# TODO: Depreciate old template extensions
|
||||
register_template_handler :rhtml, TemplateHandlers::ERB
|
||||
register_template_handler :rxml, TemplateHandlers::Builder
|
||||
|
||||
def raise_missing_template_exception
|
||||
full_template_path = @path.include?('.') ? @path : "#{@path}.#{@view.template_format}.erb"
|
||||
display_paths = @finder.view_paths.join(':')
|
||||
template_type = (@path =~ /layouts/i) ? 'layout' : 'template'
|
||||
raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
module ActionView #:nodoc:
|
||||
class TemplateFinder #:nodoc:
|
||||
|
||||
class InvalidViewPath < StandardError #:nodoc:
|
||||
attr_reader :unprocessed_path
|
||||
def initialize(path)
|
||||
@unprocessed_path = path
|
||||
super("Unprocessed view path found: #{@unprocessed_path.inspect}. Set your view paths with #append_view_path, #prepend_view_path, or #view_paths=.")
|
||||
end
|
||||
end
|
||||
|
||||
cattr_reader :processed_view_paths
|
||||
@@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
|
||||
|
||||
@@ -18,7 +9,6 @@ module ActionView #:nodoc:
|
||||
}
|
||||
|
||||
class << self #:nodoc:
|
||||
|
||||
# This method is not thread safe. Mutex should be used whenever this is accessed from an instance method
|
||||
def process_view_paths(*view_paths)
|
||||
view_paths.flatten.compact.each do |dir|
|
||||
@@ -35,7 +25,7 @@ module ActionView #:nodoc:
|
||||
|
||||
# Build extension cache
|
||||
extension = file.split(".").last
|
||||
if template_handler_extensions.include?(extension)
|
||||
if ActionView::Template.template_handler_extensions.include?(extension)
|
||||
key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
|
||||
@@file_extension_cache[dir][key] << extension
|
||||
end
|
||||
@@ -44,19 +34,6 @@ module ActionView #:nodoc:
|
||||
end
|
||||
end
|
||||
|
||||
def update_extension_cache_for(extension)
|
||||
@@processed_view_paths.keys.each do |dir|
|
||||
Dir.glob("#{dir}/**/*.#{extension}").each do |file|
|
||||
key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
|
||||
@@file_extension_cache[dir][key] << extension
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def template_handler_extensions
|
||||
ActionView::Template.template_handler_extensions
|
||||
end
|
||||
|
||||
def reload!
|
||||
view_paths = @@processed_view_paths.keys
|
||||
|
||||
@@ -76,7 +53,7 @@ module ActionView #:nodoc:
|
||||
|
||||
@view_paths = args.flatten
|
||||
@view_paths = @view_paths.respond_to?(:find) ? @view_paths.dup : [*@view_paths].compact
|
||||
check_view_paths(@view_paths)
|
||||
self.class.process_view_paths(@view_paths)
|
||||
end
|
||||
|
||||
def prepend_view_path(path)
|
||||
@@ -166,12 +143,5 @@ module ActionView #:nodoc:
|
||||
def find_template_extension_from_first_render
|
||||
File.basename(@template.first_render.to_s)[/^[^.]+\.(.+)$/, 1]
|
||||
end
|
||||
|
||||
private
|
||||
def check_view_paths(view_paths)
|
||||
view_paths.each do |path|
|
||||
raise InvalidViewPath.new(path) unless @@processed_view_paths.has_key?(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module ActionView
|
||||
class TemplateHandler
|
||||
|
||||
def self.line_offset
|
||||
0
|
||||
end
|
||||
|
||||
46
actionpack/lib/action_view/template_handlers.rb
Normal file
46
actionpack/lib/action_view/template_handlers.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
require 'action_view/template_handler'
|
||||
require 'action_view/template_handlers/compilable'
|
||||
require 'action_view/template_handlers/builder'
|
||||
require 'action_view/template_handlers/erb'
|
||||
require 'action_view/template_handlers/rjs'
|
||||
|
||||
module ActionView #:nodoc:
|
||||
module TemplateHandlers #:nodoc:
|
||||
def self.extended(base)
|
||||
base.register_default_template_handler :erb, TemplateHandlers::ERB
|
||||
base.register_template_handler :rjs, TemplateHandlers::RJS
|
||||
base.register_template_handler :builder, TemplateHandlers::Builder
|
||||
|
||||
# TODO: Depreciate old template extensions
|
||||
base.register_template_handler :rhtml, TemplateHandlers::ERB
|
||||
base.register_template_handler :rxml, TemplateHandlers::Builder
|
||||
end
|
||||
|
||||
@@template_handlers = {}
|
||||
@@default_template_handlers = nil
|
||||
|
||||
# Register a class that knows how to handle template files with the given
|
||||
# extension. This can be used to implement new template types.
|
||||
# The constructor for the class must take the ActiveView::Base instance
|
||||
# as a parameter, and the class must implement a +render+ method that
|
||||
# takes the contents of the template to render as well as the Hash of
|
||||
# local assigns available to the template. The +render+ method ought to
|
||||
# return the rendered template as a string.
|
||||
def register_template_handler(extension, klass)
|
||||
@@template_handlers[extension.to_sym] = klass
|
||||
end
|
||||
|
||||
def template_handler_extensions
|
||||
@@template_handlers.keys.map(&:to_s).sort
|
||||
end
|
||||
|
||||
def register_default_template_handler(extension, klass)
|
||||
register_template_handler(extension, klass)
|
||||
@@default_template_handlers = klass
|
||||
end
|
||||
|
||||
def handler_class_for_extension(extension)
|
||||
(extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -11,10 +11,11 @@ module ActionView
|
||||
|
||||
def compile(template)
|
||||
content_type_handler = (@view.send!(:controller).respond_to?(:response) ? "controller.response" : "controller")
|
||||
|
||||
"#{content_type_handler}.content_type ||= Mime::XML\n" +
|
||||
"xml = ::Builder::XmlMarkup.new(:indent => 2)\n" +
|
||||
template.source +
|
||||
"\nxml.target!\n"
|
||||
"xml = ::Builder::XmlMarkup.new(:indent => 2)\n" +
|
||||
template.source +
|
||||
"\nxml.target!\n"
|
||||
end
|
||||
|
||||
def cache_fragment(block, name = {}, options = nil)
|
||||
|
||||
@@ -106,7 +106,7 @@ module ActionView
|
||||
locals_code << "#{key} = local_assigns[:#{key}]\n"
|
||||
end
|
||||
|
||||
"def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
|
||||
"def #{render_symbol}(local_assigns)\nold_output_buffer = output_buffer;#{locals_code}#{body}\nensure\nself.output_buffer = old_output_buffer\nend"
|
||||
end
|
||||
|
||||
# Return true if the given template was compiled for a superset of the keys in local_assigns
|
||||
@@ -125,4 +125,4 @@ module ActionView
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,13 +43,11 @@ module ActionView
|
||||
include Compilable
|
||||
|
||||
def compile(template)
|
||||
::ERB.new(template.source, nil, @view.erb_trim_mode).src
|
||||
::ERB.new(template.source, nil, @view.erb_trim_mode, '@output_buffer').src
|
||||
end
|
||||
|
||||
def cache_fragment(block, name = {}, options = nil) #:nodoc:
|
||||
@view.fragment_for(block, name, options) do
|
||||
eval(ActionView::Base.erb_variable, block.binding)
|
||||
end
|
||||
@view.fragment_for(block, name, options) { @view.response.template.output_buffer ||= '' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,6 +37,8 @@ module ActionView
|
||||
if helper_class && !self.class.ancestors.include?(helper_class)
|
||||
self.class.send(:include, helper_class)
|
||||
end
|
||||
|
||||
self.output_buffer = ''
|
||||
end
|
||||
|
||||
class TestController < ActionController::Base
|
||||
@@ -48,6 +50,9 @@ module ActionView
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
attr_accessor :output_buffer
|
||||
|
||||
private
|
||||
def method_missing(selector, *args)
|
||||
controller = TestController.new
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'fileutils'
|
||||
require 'abstract_unit'
|
||||
require "active_support/cache/memory_store"
|
||||
|
||||
CACHE_DIR = 'test_cache'
|
||||
# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
|
||||
@@ -188,6 +189,10 @@ class ActionCachingTestController < ActionController::Base
|
||||
expire_action :controller => 'action_caching_test', :action => 'index'
|
||||
render :nothing => true
|
||||
end
|
||||
def expire_xml
|
||||
expire_action :controller => 'action_caching_test', :action => 'index', :format => 'xml'
|
||||
render :nothing => true
|
||||
end
|
||||
end
|
||||
|
||||
class MockTime < Time
|
||||
@@ -213,6 +218,7 @@ class ActionCachingMockController
|
||||
mocked_path = @mock_path
|
||||
Object.new.instance_eval(<<-EVAL)
|
||||
def path; '#{@mock_path}' end
|
||||
def format; 'all' end
|
||||
self
|
||||
EVAL
|
||||
end
|
||||
@@ -326,6 +332,20 @@ class ActionCacheTest < Test::Unit::TestCase
|
||||
assert_equal new_cached_time, @response.body
|
||||
end
|
||||
|
||||
def test_cache_expiration_isnt_affected_by_request_format
|
||||
get :index
|
||||
cached_time = content_to_cache
|
||||
reset!
|
||||
|
||||
@request.set_REQUEST_URI "/action_caching_test/expire.xml"
|
||||
get :expire, :format => :xml
|
||||
reset!
|
||||
|
||||
get :index
|
||||
new_cached_time = content_to_cache
|
||||
assert_not_equal cached_time, @response.body
|
||||
end
|
||||
|
||||
def test_cache_is_scoped_by_subdomain
|
||||
@request.host = 'jamis.hostname.com'
|
||||
get :index
|
||||
@@ -370,11 +390,35 @@ class ActionCacheTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_xml_version_of_resource_is_treated_as_different_cache
|
||||
@mock_controller.mock_url_for = 'http://example.org/posts/'
|
||||
@mock_controller.mock_path = '/posts/index.xml'
|
||||
path_object = @path_class.new(@mock_controller, {})
|
||||
assert_equal 'xml', path_object.extension
|
||||
assert_equal 'example.org/posts/index.xml', path_object.path
|
||||
with_routing do |set|
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.connect ':controller/:action.:format'
|
||||
map.connect ':controller/:action'
|
||||
end
|
||||
|
||||
get :index, :format => 'xml'
|
||||
cached_time = content_to_cache
|
||||
assert_equal cached_time, @response.body
|
||||
assert fragment_exist?('hostname.com/action_caching_test/index.xml')
|
||||
reset!
|
||||
|
||||
get :index, :format => 'xml'
|
||||
assert_equal cached_time, @response.body
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
reset!
|
||||
|
||||
@request.env['HTTP_ACCEPT'] = "application/xml"
|
||||
get :index
|
||||
assert_equal cached_time, @response.body
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
reset!
|
||||
|
||||
get :expire_xml
|
||||
reset!
|
||||
|
||||
get :index, :format => 'xml'
|
||||
assert_not_equal cached_time, @response.body
|
||||
end
|
||||
end
|
||||
|
||||
def test_correct_content_type_is_returned_for_cache_hit
|
||||
@@ -436,6 +480,8 @@ class FragmentCachingTest < Test::Unit::TestCase
|
||||
@controller.request = @request
|
||||
@controller.response = @response
|
||||
@controller.send(:initialize_current_url)
|
||||
@controller.send(:initialize_template_class, @response)
|
||||
@controller.send(:assign_shortcuts, @request, @response)
|
||||
end
|
||||
|
||||
def test_fragment_cache_key
|
||||
@@ -525,7 +571,7 @@ class FragmentCachingTest < Test::Unit::TestCase
|
||||
|
||||
def test_cache_erb_fragment
|
||||
@store.write('views/expensive', 'fragment content')
|
||||
_erbout = 'generated till now -> '
|
||||
@controller.response.template.output_buffer = 'generated till now -> '
|
||||
|
||||
assert_equal( 'generated till now -> fragment content',
|
||||
ActionView::TemplateHandlers::ERB.new(@controller).cache_fragment(Proc.new{ }, 'expensive'))
|
||||
|
||||
@@ -11,19 +11,11 @@ class CaptureController < ActionController::Base
|
||||
def content_for_with_parameter
|
||||
render :layout => "talk_from_action"
|
||||
end
|
||||
|
||||
|
||||
def content_for_concatenated
|
||||
render :layout => "talk_from_action"
|
||||
end
|
||||
|
||||
def erb_content_for
|
||||
render :layout => "talk_from_action"
|
||||
end
|
||||
|
||||
def block_content_for
|
||||
render :layout => "talk_from_action"
|
||||
end
|
||||
|
||||
def non_erb_block_content_for
|
||||
render :layout => "talk_from_action"
|
||||
end
|
||||
@@ -62,21 +54,11 @@ class CaptureTest < Test::Unit::TestCase
|
||||
assert_equal expected_content_for_output, @response.body
|
||||
end
|
||||
|
||||
def test_erb_content_for
|
||||
get :erb_content_for
|
||||
assert_equal expected_content_for_output, @response.body
|
||||
end
|
||||
|
||||
def test_should_set_content_for_with_parameter
|
||||
get :content_for_with_parameter
|
||||
assert_equal expected_content_for_output, @response.body
|
||||
end
|
||||
|
||||
def test_block_content_for
|
||||
get :block_content_for
|
||||
assert_equal expected_content_for_output, @response.body
|
||||
end
|
||||
|
||||
def test_non_erb_block_content_for
|
||||
get :non_erb_block_content_for
|
||||
assert_equal expected_content_for_output, @response.body
|
||||
|
||||
@@ -115,35 +115,37 @@ class CgiRequestNeedsRewoundTest < BaseCgiTest
|
||||
end
|
||||
end
|
||||
|
||||
class CgiResponseTest < BaseCgiTest
|
||||
def setup
|
||||
super
|
||||
@fake_cgi.expects(:header).returns("HTTP/1.0 200 OK\nContent-Type: text/html\n")
|
||||
@response = ActionController::CgiResponse.new(@fake_cgi)
|
||||
@output = StringIO.new('')
|
||||
end
|
||||
|
||||
def test_simple_output
|
||||
@response.body = "Hello, World!"
|
||||
|
||||
@response.out(@output)
|
||||
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\nHello, World!", @output.string
|
||||
end
|
||||
|
||||
def test_head_request
|
||||
@fake_cgi.env_table['REQUEST_METHOD'] = 'HEAD'
|
||||
@response.body = "Hello, World!"
|
||||
|
||||
@response.out(@output)
|
||||
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n", @output.string
|
||||
end
|
||||
|
||||
def test_streaming_block
|
||||
@response.body = Proc.new do |response, output|
|
||||
5.times { |n| output.write(n) }
|
||||
uses_mocha 'CGI Response' do
|
||||
class CgiResponseTest < BaseCgiTest
|
||||
def setup
|
||||
super
|
||||
@fake_cgi.expects(:header).returns("HTTP/1.0 200 OK\nContent-Type: text/html\n")
|
||||
@response = ActionController::CgiResponse.new(@fake_cgi)
|
||||
@output = StringIO.new('')
|
||||
end
|
||||
|
||||
@response.out(@output)
|
||||
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n01234", @output.string
|
||||
def test_simple_output
|
||||
@response.body = "Hello, World!"
|
||||
|
||||
@response.out(@output)
|
||||
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\nHello, World!", @output.string
|
||||
end
|
||||
|
||||
def test_head_request
|
||||
@fake_cgi.env_table['REQUEST_METHOD'] = 'HEAD'
|
||||
@response.body = "Hello, World!"
|
||||
|
||||
@response.out(@output)
|
||||
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n", @output.string
|
||||
end
|
||||
|
||||
def test_streaming_block
|
||||
@response.body = Proc.new do |response, output|
|
||||
5.times { |n| output.write(n) }
|
||||
end
|
||||
|
||||
@response.out(@output)
|
||||
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n01234", @output.string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -68,6 +68,11 @@ class NewRenderTestController < ActionController::Base
|
||||
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
|
||||
render :file => path
|
||||
end
|
||||
|
||||
def render_file_from_template
|
||||
@secret = 'in the sauce'
|
||||
@path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb'))
|
||||
end
|
||||
|
||||
def render_file_with_locals
|
||||
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')
|
||||
@@ -215,7 +220,7 @@ class NewRenderTestController < ActionController::Base
|
||||
render :action => "test/hello_world"
|
||||
end
|
||||
|
||||
def render_to_string_with_partial
|
||||
def render_to_string_with_partial
|
||||
@partial_only = render_to_string :partial => "partial_only"
|
||||
@partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }
|
||||
render :action => "test/hello_world"
|
||||
@@ -246,11 +251,15 @@ class NewRenderTestController < ActionController::Base
|
||||
def accessing_logger_in_template
|
||||
render :inline => "<%= logger.class %>"
|
||||
end
|
||||
|
||||
|
||||
def accessing_action_name_in_template
|
||||
render :inline => "<%= action_name %>"
|
||||
end
|
||||
|
||||
def accessing_controller_name_in_template
|
||||
render :inline => "<%= controller_name %>"
|
||||
end
|
||||
|
||||
def accessing_params_in_template_with_layout
|
||||
render :layout => nil, :inline => "Hello: <%= params[:name] %>"
|
||||
end
|
||||
@@ -531,6 +540,11 @@ class NewRenderTest < Test::Unit::TestCase
|
||||
get :render_file_with_locals
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
def test_render_file_from_template
|
||||
get :render_file_from_template
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
def test_attempt_to_access_object_method
|
||||
assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { get :clone }
|
||||
@@ -549,12 +563,17 @@ class NewRenderTest < Test::Unit::TestCase
|
||||
get :accessing_logger_in_template
|
||||
assert_equal "Logger", @response.body
|
||||
end
|
||||
|
||||
|
||||
def test_access_to_action_name_in_view
|
||||
get :accessing_action_name_in_template
|
||||
assert_equal "accessing_action_name_in_template", @response.body
|
||||
end
|
||||
|
||||
def test_access_to_controller_name_in_view
|
||||
get :accessing_controller_name_in_template
|
||||
assert_equal "test", @response.body # name is explicitly set to 'test' inside the controller.
|
||||
end
|
||||
|
||||
def test_render_xml
|
||||
get :render_xml_hello
|
||||
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
|
||||
@@ -742,7 +761,7 @@ EOS
|
||||
|
||||
def test_partial_collection_with_counter
|
||||
get :partial_collection_with_counter
|
||||
assert_equal "david1mary2", @response.body
|
||||
assert_equal "david0mary1", @response.body
|
||||
end
|
||||
|
||||
def test_partial_collection_with_locals
|
||||
@@ -762,7 +781,7 @@ EOS
|
||||
|
||||
def test_partial_collection_shorthand_with_different_types_of_records
|
||||
get :partial_collection_shorthand_with_different_types_of_records
|
||||
assert_equal "Bonjour bad customer: mark1Bonjour good customer: craig2Bonjour bad customer: john3Bonjour good customer: zach4Bonjour good customer: brandon5Bonjour bad customer: dan6", @response.body
|
||||
assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body
|
||||
end
|
||||
|
||||
def test_empty_partial_collection
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
require 'abstract_unit'
|
||||
require 'action_controller/cgi_process'
|
||||
require 'action_controller/cgi_ext'
|
||||
|
||||
require 'action_controller/session/mem_cache_store'
|
||||
|
||||
class CGI::Session
|
||||
def cache
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<% block_content_for :title do 'Putting stuff in the title!' end %>
|
||||
Great stuff!
|
||||
@@ -1,2 +0,0 @@
|
||||
<% erb_content_for :title do %>Putting stuff in the title!<% end %>
|
||||
Great stuff!
|
||||
1
actionpack/test/fixtures/test/render_file_from_template.html.erb
vendored
Normal file
1
actionpack/test/fixtures/test/render_file_from_template.html.erb
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<%= render :file => @path %>
|
||||
@@ -1002,17 +1002,15 @@ class DateHelperTest < ActionView::TestCase
|
||||
@post = Post.new
|
||||
@post.written_on = Date.new(2004, 6, 15)
|
||||
|
||||
_erbout = ''
|
||||
|
||||
fields_for :post, @post do |f|
|
||||
_erbout.concat f.date_select(:written_on)
|
||||
concat f.date_select(:written_on)
|
||||
end
|
||||
|
||||
expected = "<select id='post_written_on_1i' name='post[written_on(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
|
||||
expected << "<select id='post_written_on_2i' name='post[written_on(2i)]'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
|
||||
expected << "<select id='post_written_on_3i' name='post[written_on(3i)]'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
|
||||
|
||||
assert_dom_equal(expected, _erbout)
|
||||
assert_dom_equal(expected, output_buffer)
|
||||
end
|
||||
|
||||
def test_date_select_with_index
|
||||
@@ -1287,10 +1285,8 @@ class DateHelperTest < ActionView::TestCase
|
||||
@post = Post.new
|
||||
@post.updated_at = Time.local(2004, 6, 15, 16, 35)
|
||||
|
||||
_erbout = ''
|
||||
|
||||
fields_for :post, @post do |f|
|
||||
_erbout.concat f.datetime_select(:updated_at)
|
||||
concat f.datetime_select(:updated_at)
|
||||
end
|
||||
|
||||
expected = "<select id='post_updated_at_1i' name='post[updated_at(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
|
||||
@@ -1299,7 +1295,7 @@ class DateHelperTest < ActionView::TestCase
|
||||
expected << " — <select id='post_updated_at_4i' name='post[updated_at(4i)]'>\n<option value='00'>00</option>\n<option value='01'>01</option>\n<option value='02'>02</option>\n<option value='03'>03</option>\n<option value='04'>04</option>\n<option value='05'>05</option>\n<option value='06'>06</option>\n<option value='07'>07</option>\n<option value='08'>08</option>\n<option value='09'>09</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option value='15'>15</option>\n<option selected='selected' value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n</select>\n"
|
||||
expected << " : <select id='post_updated_at_5i' name='post[updated_at(5i)]'>\n<option value='00'>00</option>\n<option value='01'>01</option>\n<option value='02'>02</option>\n<option value='03'>03</option>\n<option value='04'>04</option>\n<option value='05'>05</option>\n<option value='06'>06</option>\n<option value='07'>07</option>\n<option value='08'>08</option>\n<option value='09'>09</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n<option value='32'>32</option>\n<option value='33'>33</option>\n<option value='34'>34</option>\n<option selected='selected' value='35'>35</option>\n<option value='36'>36</option>\n<option value='37'>37</option>\n<option value='38'>38</option>\n<option value='39'>39</option>\n<option value='40'>40</option>\n<option value='41'>41</option>\n<option value='42'>42</option>\n<option value='43'>43</option>\n<option value='44'>44</option>\n<option value='45'>45</option>\n<option value='46'>46</option>\n<option value='47'>47</option>\n<option value='48'>48</option>\n<option value='49'>49</option>\n<option value='50'>50</option>\n<option value='51'>51</option>\n<option value='52'>52</option>\n<option value='53'>53</option>\n<option value='54'>54</option>\n<option value='55'>55</option>\n<option value='56'>56</option>\n<option value='57'>57</option>\n<option value='58'>58</option>\n<option value='59'>59</option>\n</select>\n"
|
||||
|
||||
assert_dom_equal(expected, _erbout)
|
||||
assert_dom_equal(expected, output_buffer)
|
||||
end
|
||||
|
||||
def test_date_select_with_zero_value_and_no_start_year
|
||||
|
||||
@@ -337,14 +337,12 @@ class FormHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_form_for
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
|
||||
_erbout.concat f.label(:title)
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
_erbout.concat f.submit('Create post')
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
concat f.submit('Create post')
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -357,16 +355,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='commit' id='post_submit' type='submit' value='Create post' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_method
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -378,16 +374,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' type='hidden' value='0' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_without_object
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, :html => { :id => 'create-post' }) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -398,17 +392,15 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' type='hidden' value='0' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_index
|
||||
_erbout = ''
|
||||
|
||||
form_for("post[]", @post) do |f|
|
||||
_erbout.concat f.label(:title)
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -420,16 +412,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[123][secret]' type='hidden' value='0' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_nil_index_option_override
|
||||
_erbout = ''
|
||||
|
||||
form_for("post[]", @post, :index => nil) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -440,14 +430,13 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[][secret]' type='hidden' value='0' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for
|
||||
_erbout = ''
|
||||
form_for(:post, @post) do |f|
|
||||
f.fields_for(:comment, @post) do |c|
|
||||
_erbout.concat c.text_field(:title)
|
||||
concat c.text_field(:title)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -455,16 +444,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[comment][title]' size='30' type='text' id='post_comment_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for
|
||||
_erbout = ''
|
||||
|
||||
fields_for(:post, @post) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -473,16 +460,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
|
||||
"<input name='post[secret]' type='hidden' value='0' />"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_with_index
|
||||
_erbout = ''
|
||||
|
||||
fields_for("post[]", @post) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -491,16 +476,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
|
||||
"<input name='post[123][secret]' type='hidden' value='0' />"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_with_nil_index_option_override
|
||||
_erbout = ''
|
||||
|
||||
fields_for("post[]", @post, :index => nil) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -509,16 +492,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
|
||||
"<input name='post[][secret]' type='hidden' value='0' />"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_with_index_option_override
|
||||
_erbout = ''
|
||||
|
||||
fields_for("post[]", @post, :index => "abc") do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -527,15 +508,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />" +
|
||||
"<input name='post[abc][secret]' type='hidden' value='0' />"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_without_object
|
||||
_erbout = ''
|
||||
fields_for(:post) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -544,15 +524,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
|
||||
"<input name='post[secret]' type='hidden' value='0' />"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_with_only_object
|
||||
_erbout = ''
|
||||
fields_for(@post) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -561,31 +540,29 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
|
||||
"<input name='post[secret]' type='hidden' value='0' />"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_object_with_bracketed_name
|
||||
_erbout = ''
|
||||
fields_for("author[post]", @post) do |f|
|
||||
_erbout.concat f.label(:title)
|
||||
_erbout.concat f.text_field(:title)
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
end
|
||||
|
||||
assert_dom_equal "<label for=\"author_post_title\">Title</label>" +
|
||||
"<input name='author[post][title]' size='30' type='text' id='author_post_title' value='Hello World' />",
|
||||
_erbout
|
||||
output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_object_with_bracketed_name_and_index
|
||||
_erbout = ''
|
||||
fields_for("author[post]", @post, :index => 1) do |f|
|
||||
_erbout.concat f.label(:title)
|
||||
_erbout.concat f.text_field(:title)
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
end
|
||||
|
||||
assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" +
|
||||
"<input name='author[post][1][title]' size='30' type='text' id='author_post_1_title' value='Hello World' />",
|
||||
_erbout
|
||||
output_buffer
|
||||
end
|
||||
|
||||
def test_form_builder_does_not_have_form_for_method
|
||||
@@ -593,14 +570,12 @@ class FormHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_form_for_and_fields_for
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
|
||||
_erbout.concat post_form.text_field(:title)
|
||||
_erbout.concat post_form.text_area(:body)
|
||||
concat post_form.text_field(:title)
|
||||
concat post_form.text_area(:body)
|
||||
|
||||
fields_for(:parent_post, @post) do |parent_fields|
|
||||
_erbout.concat parent_fields.check_box(:secret)
|
||||
concat parent_fields.check_box(:secret)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -612,18 +587,16 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='parent_post[secret]' type='hidden' value='0' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_and_fields_for_with_object
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
|
||||
_erbout.concat post_form.text_field(:title)
|
||||
_erbout.concat post_form.text_area(:body)
|
||||
concat post_form.text_field(:title)
|
||||
concat post_form.text_area(:body)
|
||||
|
||||
post_form.fields_for(@comment) do |comment_fields|
|
||||
_erbout.concat comment_fields.text_field(:name)
|
||||
concat comment_fields.text_field(:name)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -634,7 +607,7 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
class LabelledFormBuilder < ActionView::Helpers::FormBuilder
|
||||
@@ -649,12 +622,10 @@ class FormHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_form_for_with_labelled_builder
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -665,18 +636,17 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_default_form_builder
|
||||
old_default_form_builder, ActionView::Base.default_form_builder =
|
||||
ActionView::Base.default_form_builder, LabelledFormBuilder
|
||||
|
||||
_erbout = ''
|
||||
form_for(:post, @post) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -687,17 +657,15 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
ensure
|
||||
ActionView::Base.default_form_builder = old_default_form_builder
|
||||
end
|
||||
|
||||
def test_default_form_builder_with_active_record_helpers
|
||||
|
||||
_erbout = ''
|
||||
form_for(:post, @post) do |f|
|
||||
_erbout.concat f.error_message_on('author_name')
|
||||
_erbout.concat f.error_messages
|
||||
concat f.error_message_on('author_name')
|
||||
concat f.error_messages
|
||||
end
|
||||
|
||||
expected = %(<form action='http://www.example.com' method='post'>) +
|
||||
@@ -705,7 +673,7 @@ class FormHelperTest < ActionView::TestCase
|
||||
%(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
|
||||
%(</form>)
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
||||
end
|
||||
|
||||
@@ -713,10 +681,9 @@ class FormHelperTest < ActionView::TestCase
|
||||
post = @post
|
||||
@post = nil
|
||||
|
||||
_erbout = ''
|
||||
form_for(:post, post) do |f|
|
||||
_erbout.concat f.error_message_on('author_name')
|
||||
_erbout.concat f.error_messages
|
||||
concat f.error_message_on('author_name')
|
||||
concat f.error_messages
|
||||
end
|
||||
|
||||
expected = %(<form action='http://www.example.com' method='post'>) +
|
||||
@@ -724,19 +691,18 @@ class FormHelperTest < ActionView::TestCase
|
||||
%(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
|
||||
%(</form>)
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
||||
end
|
||||
|
||||
# Perhaps this test should be moved to prototype helper tests.
|
||||
def test_remote_form_for_with_labelled_builder
|
||||
self.extend ActionView::Helpers::PrototypeHelper
|
||||
_erbout = ''
|
||||
|
||||
remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -747,16 +713,14 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for_with_labelled_builder
|
||||
_erbout = ''
|
||||
|
||||
fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
_erbout.concat f.text_field(:title)
|
||||
_erbout.concat f.text_area(:body)
|
||||
_erbout.concat f.check_box(:secret)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
|
||||
expected =
|
||||
@@ -765,29 +729,23 @@ class FormHelperTest < ActionView::TestCase
|
||||
"<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
|
||||
"<input name='post[secret]' type='hidden' value='0' /><br/>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_html_options_adds_options_to_form_tag
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
|
||||
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_string_url_option
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
|
||||
|
||||
assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', _erbout
|
||||
assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_hash_url_option
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
|
||||
|
||||
assert_equal 'controller', @controller.url_for_options[:controller]
|
||||
@@ -795,26 +753,20 @@ class FormHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_form_for_with_record_url_option
|
||||
_erbout = ''
|
||||
|
||||
form_for(:post, @post, :url => @post) do |f| end
|
||||
|
||||
expected = "<form action=\"/posts/123\" method=\"post\"></form>"
|
||||
assert_equal expected, _erbout
|
||||
assert_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_existing_object
|
||||
_erbout = ''
|
||||
|
||||
form_for(@post) do |f| end
|
||||
|
||||
expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
|
||||
assert_equal expected, _erbout
|
||||
assert_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_new_object
|
||||
_erbout = ''
|
||||
|
||||
post = Post.new
|
||||
post.new_record = true
|
||||
def post.id() nil end
|
||||
@@ -822,64 +774,61 @@ class FormHelperTest < ActionView::TestCase
|
||||
form_for(post) do |f| end
|
||||
|
||||
expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
|
||||
assert_equal expected, _erbout
|
||||
assert_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_existing_object_in_list
|
||||
@post.new_record = false
|
||||
@comment.save
|
||||
_erbout = ''
|
||||
|
||||
form_for([@post, @comment]) {}
|
||||
|
||||
expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_new_object_in_list
|
||||
@post.new_record = false
|
||||
_erbout = ''
|
||||
|
||||
form_for([@post, @comment]) {}
|
||||
|
||||
expected = %(<form action="#{comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_existing_object_and_namespace_in_list
|
||||
@post.new_record = false
|
||||
@comment.save
|
||||
_erbout = ''
|
||||
|
||||
form_for([:admin, @post, @comment]) {}
|
||||
|
||||
expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_new_object_and_namespace_in_list
|
||||
@post.new_record = false
|
||||
_erbout = ''
|
||||
|
||||
form_for([:admin, @post, @comment]) {}
|
||||
|
||||
expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_existing_object_and_custom_url
|
||||
_erbout = ''
|
||||
|
||||
form_for(@post, :url => "/super_posts") do |f| end
|
||||
|
||||
expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
|
||||
assert_equal expected, _erbout
|
||||
assert_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_remote_form_for_with_html_options_adds_options_to_form_tag
|
||||
self.extend ActionView::Helpers::PrototypeHelper
|
||||
_erbout = ''
|
||||
|
||||
remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
|
||||
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\" onsubmit=\"new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"></form>"
|
||||
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ class MockTimeZone
|
||||
end
|
||||
end
|
||||
|
||||
ActionView::Helpers::FormOptionsHelper::TimeZone = MockTimeZone
|
||||
|
||||
class FormOptionsHelperTest < ActionView::TestCase
|
||||
tests ActionView::Helpers::FormOptionsHelper
|
||||
|
||||
@@ -31,6 +29,8 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
Country = Struct.new('Country', :country_id, :country_name)
|
||||
Firm = Struct.new('Firm', :time_zone)
|
||||
Album = Struct.new('Album', :id, :title, :genre)
|
||||
|
||||
ActiveSupport::TimeZone = MockTimeZone
|
||||
end
|
||||
|
||||
def test_collection_options
|
||||
@@ -183,7 +183,7 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_time_zone_options_with_priority_zones
|
||||
zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
|
||||
zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ]
|
||||
opts = time_zone_options_for_select( nil, zones )
|
||||
assert_dom_equal "<option value=\"B\">B</option>\n" +
|
||||
"<option value=\"E\">E</option>" +
|
||||
@@ -195,7 +195,7 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_time_zone_options_with_selected_priority_zones
|
||||
zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
|
||||
zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ]
|
||||
opts = time_zone_options_for_select( "E", zones )
|
||||
assert_dom_equal "<option value=\"B\">B</option>\n" +
|
||||
"<option value=\"E\" selected=\"selected\">E</option>" +
|
||||
@@ -207,7 +207,7 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_time_zone_options_with_unselected_priority_zones
|
||||
zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
|
||||
zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ]
|
||||
opts = time_zone_options_for_select( "C", zones )
|
||||
assert_dom_equal "<option value=\"B\">B</option>\n" +
|
||||
"<option value=\"E\">E</option>" +
|
||||
@@ -230,16 +230,14 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
def test_select_under_fields_for
|
||||
@post = Post.new
|
||||
@post.category = "<mus>"
|
||||
|
||||
_erbout = ''
|
||||
|
||||
|
||||
fields_for :post, @post do |f|
|
||||
_erbout.concat f.select(:category, %w( abe <mus> hest))
|
||||
concat f.select(:category, %w( abe <mus> hest))
|
||||
end
|
||||
|
||||
assert_dom_equal(
|
||||
"<select id=\"post_category\" name=\"post[category]\"><option value=\"abe\">abe</option>\n<option value=\"<mus>\" selected=\"selected\"><mus></option>\n<option value=\"hest\">hest</option></select>",
|
||||
_erbout
|
||||
output_buffer
|
||||
)
|
||||
end
|
||||
|
||||
@@ -352,16 +350,14 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
|
||||
@post = Post.new
|
||||
@post.author_name = "Babe"
|
||||
|
||||
_erbout = ''
|
||||
|
||||
|
||||
fields_for :post, @post do |f|
|
||||
_erbout.concat f.collection_select(:author_name, @posts, :author_name, :author_name)
|
||||
concat f.collection_select(:author_name, @posts, :author_name, :author_name)
|
||||
end
|
||||
|
||||
assert_dom_equal(
|
||||
"<select id=\"post_author_name\" name=\"post[author_name]\"><option value=\"<Abe>\"><Abe></option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
|
||||
_erbout
|
||||
output_buffer
|
||||
)
|
||||
end
|
||||
|
||||
@@ -1194,11 +1190,9 @@ COUNTRIES
|
||||
|
||||
def test_time_zone_select_under_fields_for
|
||||
@firm = Firm.new("D")
|
||||
|
||||
_erbout = ''
|
||||
|
||||
|
||||
fields_for :firm, @firm do |f|
|
||||
_erbout.concat f.time_zone_select(:time_zone)
|
||||
concat f.time_zone_select(:time_zone)
|
||||
end
|
||||
|
||||
assert_dom_equal(
|
||||
@@ -1209,7 +1203,7 @@ COUNTRIES
|
||||
"<option value=\"D\" selected=\"selected\">D</option>\n" +
|
||||
"<option value=\"E\">E</option>" +
|
||||
"</select>",
|
||||
_erbout
|
||||
output_buffer
|
||||
)
|
||||
end
|
||||
|
||||
@@ -1293,7 +1287,7 @@ COUNTRIES
|
||||
|
||||
def test_time_zone_select_with_priority_zones
|
||||
@firm = Firm.new("D")
|
||||
zones = [ TimeZone.new("A"), TimeZone.new("D") ]
|
||||
zones = [ ActiveSupport::TimeZone.new("A"), ActiveSupport::TimeZone.new("D") ]
|
||||
html = time_zone_select("firm", "time_zone", zones )
|
||||
assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" +
|
||||
"<option value=\"A\">A</option>\n" +
|
||||
|
||||
@@ -43,19 +43,17 @@ class FormTagHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_form_tag_with_block
|
||||
_erbout = ''
|
||||
form_tag("http://example.com") { _erbout.concat "Hello world!" }
|
||||
form_tag("http://example.com") { concat "Hello world!" }
|
||||
|
||||
expected = %(<form action="http://example.com" method="post">Hello world!</form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_tag_with_block_and_method
|
||||
_erbout = ''
|
||||
form_tag("http://example.com", :method => :put) { _erbout.concat "Hello world!" }
|
||||
form_tag("http://example.com", :method => :put) { concat "Hello world!" }
|
||||
|
||||
expected = %(<form action="http://example.com" method="post"><div style='margin:0;padding:0'><input type="hidden" name="_method" value="put" /></div>Hello world!</form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_hidden_field_tag
|
||||
@@ -234,23 +232,22 @@ class FormTagHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_field_set_tag
|
||||
_erbout = ''
|
||||
field_set_tag("Your details") { _erbout.concat "Hello world!" }
|
||||
field_set_tag("Your details") { concat "Hello world!" }
|
||||
|
||||
expected = %(<fieldset><legend>Your details</legend>Hello world!</fieldset>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
||||
_erbout = ''
|
||||
field_set_tag { _erbout.concat "Hello world!" }
|
||||
self.output_buffer = ''
|
||||
field_set_tag { concat "Hello world!" }
|
||||
|
||||
expected = %(<fieldset>Hello world!</fieldset>)
|
||||
assert_dom_equal expected, _erbout
|
||||
|
||||
_erbout = ''
|
||||
field_set_tag('') { _erbout.concat "Hello world!" }
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
||||
self.output_buffer = ''
|
||||
field_set_tag('') { concat "Hello world!" }
|
||||
|
||||
expected = %(<fieldset>Hello world!</fieldset>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def protect_against_forgery?
|
||||
|
||||
@@ -82,8 +82,12 @@ class JavaScriptHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_javascript_tag
|
||||
self.output_buffer = 'foo'
|
||||
|
||||
assert_dom_equal "<script type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>",
|
||||
javascript_tag("alert('hello')")
|
||||
|
||||
assert_equal 'foo', output_buffer, 'javascript_tag without a block should not concat to output_buffer'
|
||||
end
|
||||
|
||||
def test_javascript_tag_with_options
|
||||
@@ -92,15 +96,13 @@ class JavaScriptHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_javascript_tag_with_block
|
||||
_erbout = ''
|
||||
javascript_tag { _erbout.concat "alert('hello')" }
|
||||
assert_dom_equal "<script type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", _erbout
|
||||
javascript_tag { concat "alert('hello')" }
|
||||
assert_dom_equal "<script type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", output_buffer
|
||||
end
|
||||
|
||||
def test_javascript_tag_with_block_and_options
|
||||
_erbout = ''
|
||||
javascript_tag(:id => "the_js_tag") { _erbout.concat "alert('hello')" }
|
||||
assert_dom_equal "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", _erbout
|
||||
javascript_tag(:id => "the_js_tag") { concat "alert('hello')" }
|
||||
assert_dom_equal "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", output_buffer
|
||||
end
|
||||
|
||||
def test_javascript_cdata_section
|
||||
|
||||
@@ -118,52 +118,46 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
|
||||
end
|
||||
|
||||
def test_form_remote_tag_with_block
|
||||
_erbout = ''
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { _erbout.concat "Hello world!" }
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">Hello world!</form>), _erbout
|
||||
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { concat "Hello world!" }
|
||||
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">Hello world!</form>), output_buffer
|
||||
end
|
||||
|
||||
def test_remote_form_for_with_record_identification_with_new_record
|
||||
_erbout = ''
|
||||
remote_form_for(@record, {:html => { :id => 'create-author' }}) {}
|
||||
|
||||
expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' id='create-author' method='post'></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_remote_form_for_with_record_identification_without_html_options
|
||||
_erbout = ''
|
||||
remote_form_for(@record) {}
|
||||
|
||||
expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' method='post' id='new_author'></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_remote_form_for_with_record_identification_with_existing_record
|
||||
@record.save
|
||||
_erbout = ''
|
||||
remote_form_for(@record) {}
|
||||
|
||||
expected = %(<form action='#{author_path(@record)}' id='edit_author_1' method='post' onsubmit="new Ajax.Request('#{author_path(@record)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_author'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_remote_form_for_with_new_object_in_list
|
||||
_erbout = ''
|
||||
remote_form_for([@author, @article]) {}
|
||||
|
||||
expected = %(<form action='#{author_articles_path(@author)}' onsubmit="new Ajax.Request('#{author_articles_path(@author)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_article' method='post' id='new_article'></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_remote_form_for_with_existing_object_in_list
|
||||
@author.save
|
||||
@article.save
|
||||
_erbout = ''
|
||||
remote_form_for([@author, @article]) {}
|
||||
|
||||
expected = %(<form action='#{author_article_path(@author, @article)}' id='edit_article_1' method='post' onsubmit="new Ajax.Request('#{author_article_path(@author, @article)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_article'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div></form>)
|
||||
assert_dom_equal expected, _erbout
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_on_callbacks
|
||||
|
||||
@@ -17,37 +17,32 @@ class RecordTagHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_content_tag_for
|
||||
_erbout = ''
|
||||
expected = %(<li class="post bar" id="post_45"></li>)
|
||||
actual = content_tag_for(:li, @post, :class => 'bar') { }
|
||||
assert_dom_equal expected, actual
|
||||
end
|
||||
|
||||
def test_content_tag_for_prefix
|
||||
_erbout = ''
|
||||
expected = %(<ul class="post" id="archived_post_45"></ul>)
|
||||
actual = content_tag_for(:ul, @post, :archived) { }
|
||||
assert_dom_equal expected, actual
|
||||
end
|
||||
|
||||
def test_content_tag_for_with_extra_html_tags
|
||||
_erbout = ''
|
||||
expected = %(<tr class="post bar" id="post_45" style='background-color: #f0f0f0'></tr>)
|
||||
actual = content_tag_for(:tr, @post, {:class => "bar", :style => "background-color: #f0f0f0"}) { }
|
||||
assert_dom_equal expected, actual
|
||||
end
|
||||
|
||||
def test_block_works_with_content_tag_for
|
||||
_erbout = ''
|
||||
expected = %(<tr class="post" id="post_45">#{@post.body}</tr>)
|
||||
actual = content_tag_for(:tr, @post) { _erbout.concat @post.body }
|
||||
actual = content_tag_for(:tr, @post) { concat @post.body }
|
||||
assert_dom_equal expected, actual
|
||||
end
|
||||
|
||||
def test_div_for
|
||||
_erbout = ''
|
||||
expected = %(<div class="post bar" id="post_45">#{@post.body}</div>)
|
||||
actual = div_for(@post, :class => "bar") { _erbout.concat @post.body }
|
||||
actual = div_for(@post, :class => "bar") { concat @post.body }
|
||||
assert_dom_equal expected, actual
|
||||
end
|
||||
|
||||
|
||||
@@ -35,18 +35,17 @@ class TagHelperTest < ActionView::TestCase
|
||||
end
|
||||
|
||||
def test_content_tag_with_block
|
||||
_erbout = ''
|
||||
content_tag(:div) { _erbout.concat "Hello world!" }
|
||||
assert_dom_equal "<div>Hello world!</div>", _erbout
|
||||
content_tag(:div) { concat "Hello world!" }
|
||||
assert_dom_equal "<div>Hello world!</div>", output_buffer
|
||||
end
|
||||
|
||||
def test_content_tag_with_block_and_options
|
||||
_erbout = ''
|
||||
content_tag(:div, :class => "green") { _erbout.concat "Hello world!" }
|
||||
assert_dom_equal %(<div class="green">Hello world!</div>), _erbout
|
||||
content_tag(:div, :class => "green") { concat "Hello world!" }
|
||||
assert_dom_equal %(<div class="green">Hello world!</div>), output_buffer
|
||||
end
|
||||
|
||||
def test_content_tag_with_block_and_options_outside_of_action_view
|
||||
self.output_buffer = nil
|
||||
assert_equal content_tag("a", "Create", :href => "create"),
|
||||
content_tag("a", "href" => "create") { "Create" }
|
||||
end
|
||||
|
||||
@@ -11,12 +11,6 @@ class TemplateFinderTest < Test::Unit::TestCase
|
||||
@finder = ActionView::TemplateFinder.new(@template, LOAD_PATH_ROOT)
|
||||
end
|
||||
|
||||
def test_should_raise_exception_for_unprocessed_view_path
|
||||
assert_raises ActionView::TemplateFinder::InvalidViewPath do
|
||||
ActionView::TemplateFinder.new(@template, File.dirname(__FILE__))
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_cache_file_extension_properly
|
||||
assert_equal ["builder", "erb", "rhtml", "rjs", "rxml", "mab"].sort,
|
||||
ActionView::TemplateFinder.file_extension_cache[LOAD_PATH_ROOT].values.flatten.uniq.sort
|
||||
@@ -63,11 +57,4 @@ class TemplateFinderTest < Test::Unit::TestCase
|
||||
assert_equal false, @finder.send(:file_exists?, 'baz')
|
||||
assert_equal false, @finder.send(:file_exists?, 'baz.rb')
|
||||
end
|
||||
|
||||
uses_mocha 'Template finder tests' do
|
||||
def test_should_update_extension_cache_when_template_handler_is_registered
|
||||
ActionView::TemplateFinder.expects(:update_extension_cache_for).with("funky")
|
||||
ActionView::Template::register_template_handler :funky, Class.new(ActionView::TemplateHandler)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,6 +11,14 @@ class TextHelperTest < ActionView::TestCase
|
||||
@_cycles = nil if (defined? @_cycles)
|
||||
end
|
||||
|
||||
def test_concat
|
||||
self.output_buffer = 'foo'
|
||||
concat 'bar'
|
||||
assert_equal 'foobar', output_buffer
|
||||
assert_nothing_raised { concat nil }
|
||||
assert_equal 'foobar', output_buffer
|
||||
end
|
||||
|
||||
def test_simple_format
|
||||
assert_equal "<p></p>", simple_format(nil)
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
*Edge*
|
||||
|
||||
* Add :from option to calculations. #397 [Ben Munat]
|
||||
|
||||
* Add :validate option to associations to enable/disable the automatic validation of associated models. Resolves #301. [Jan De Poorter]
|
||||
|
||||
* PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later. [Jeremy Kemper]
|
||||
|
||||
* Added SQL escaping for :limit and :offset in MySQL [Jonathan Wiess]
|
||||
|
||||
|
||||
|
||||
@@ -103,10 +103,10 @@ module ActiveRecord
|
||||
associated_records = reflection.klass.find(:all, :conditions => [conditions, ids],
|
||||
:include => options[:include],
|
||||
:joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} as t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
|
||||
:select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as _parent_record_id",
|
||||
:select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id",
|
||||
:order => options[:order])
|
||||
|
||||
set_association_collection_records(id_to_record_map, reflection.name, associated_records, '_parent_record_id')
|
||||
set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id')
|
||||
end
|
||||
|
||||
def preload_has_one_association(records, reflection, preload_options={})
|
||||
|
||||
@@ -690,6 +690,7 @@ module ActiveRecord
|
||||
# association is a polymorphic +belongs_to+.
|
||||
# * <tt>:uniq</tt> - If true, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>.
|
||||
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
|
||||
# * <tt>:validate</tt> - If false, don't validate the associated objects when saving the parent object. true by default.
|
||||
#
|
||||
# Option examples:
|
||||
# has_many :comments, :order => "posted_on"
|
||||
@@ -710,7 +711,7 @@ module ActiveRecord
|
||||
|
||||
configure_dependency_for_has_many(reflection)
|
||||
|
||||
add_multiple_associated_save_callbacks(reflection.name)
|
||||
add_multiple_associated_save_callbacks(reflection.name) unless options[:validate] == false
|
||||
add_association_callbacks(reflection.name, reflection.options)
|
||||
|
||||
if options[:through]
|
||||
@@ -769,6 +770,7 @@ module ActiveRecord
|
||||
# * <tt>:source_type</tt> - Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
|
||||
# association is a polymorphic +belongs_to+.
|
||||
# * <tt>:readonly</tt> - If true, the associated object is readonly through the association.
|
||||
# * <tt>:validate</tt> - If false, don't validate the associated object when saving the parent object. +false+ by default.
|
||||
#
|
||||
# Option examples:
|
||||
# has_one :credit_card, :dependent => :destroy # destroys the associated credit card
|
||||
@@ -799,7 +801,7 @@ module ActiveRecord
|
||||
end
|
||||
after_save method_name
|
||||
|
||||
add_single_associated_save_callbacks(reflection.name)
|
||||
add_single_associated_save_callbacks(reflection.name) if options[:validate] == true
|
||||
association_accessor_methods(reflection, HasOneAssociation)
|
||||
association_constructor_method(:build, reflection, HasOneAssociation)
|
||||
association_constructor_method(:create, reflection, HasOneAssociation)
|
||||
@@ -857,6 +859,7 @@ module ActiveRecord
|
||||
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
|
||||
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
|
||||
# * <tt>:readonly</tt> - If true, the associated object is readonly through the association.
|
||||
# * <tt>:validate</tt> - If false, don't validate the associated objects when saving the parent object. +false+ by default.
|
||||
#
|
||||
# Option examples:
|
||||
# belongs_to :firm, :foreign_key => "client_of"
|
||||
@@ -937,6 +940,8 @@ module ActiveRecord
|
||||
)
|
||||
end
|
||||
|
||||
add_single_associated_save_callbacks(reflection.name) if options[:validate] == true
|
||||
|
||||
configure_dependency_for_belongs_to(reflection)
|
||||
end
|
||||
|
||||
@@ -1025,6 +1030,7 @@ module ActiveRecord
|
||||
# * <tt>:select</tt> - By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join
|
||||
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# * <tt>:readonly</tt> - If true, all the associated objects are readonly through the association.
|
||||
# * <tt>:validate</tt> - If false, don't validate the associated objects when saving the parent object. +true+ by default.
|
||||
#
|
||||
# Option examples:
|
||||
# has_and_belongs_to_many :projects
|
||||
@@ -1037,7 +1043,7 @@ module ActiveRecord
|
||||
def has_and_belongs_to_many(association_id, options = {}, &extension)
|
||||
reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension)
|
||||
|
||||
add_multiple_associated_save_callbacks(reflection.name)
|
||||
add_multiple_associated_save_callbacks(reflection.name) unless options[:validate] == false
|
||||
collection_accessor_methods(reflection, HasAndBelongsToManyAssociation)
|
||||
|
||||
# Don't use a before_destroy callback since users' before_destroy
|
||||
@@ -1343,7 +1349,8 @@ module ActiveRecord
|
||||
:uniq,
|
||||
:finder_sql, :counter_sql,
|
||||
:before_add, :after_add, :before_remove, :after_remove,
|
||||
:extend, :readonly
|
||||
:extend, :readonly,
|
||||
:validate
|
||||
)
|
||||
|
||||
options[:extend] = create_extension_modules(association_id, extension, options[:extend])
|
||||
@@ -1353,7 +1360,7 @@ module ActiveRecord
|
||||
|
||||
def create_has_one_reflection(association_id, options)
|
||||
options.assert_valid_keys(
|
||||
:class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly
|
||||
:class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly, :validate
|
||||
)
|
||||
|
||||
create_reflection(:has_one, association_id, options, self)
|
||||
@@ -1361,7 +1368,7 @@ module ActiveRecord
|
||||
|
||||
def create_has_one_through_reflection(association_id, options)
|
||||
options.assert_valid_keys(
|
||||
:class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type
|
||||
:class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type, :validate
|
||||
)
|
||||
create_reflection(:has_one, association_id, options, self)
|
||||
end
|
||||
@@ -1369,7 +1376,7 @@ module ActiveRecord
|
||||
def create_belongs_to_reflection(association_id, options)
|
||||
options.assert_valid_keys(
|
||||
:class_name, :foreign_key, :foreign_type, :remote, :select, :conditions, :include, :dependent,
|
||||
:counter_cache, :extend, :polymorphic, :readonly
|
||||
:counter_cache, :extend, :polymorphic, :readonly, :validate
|
||||
)
|
||||
|
||||
reflection = create_reflection(:belongs_to, association_id, options, self)
|
||||
@@ -1388,7 +1395,8 @@ module ActiveRecord
|
||||
:uniq,
|
||||
:finder_sql, :delete_sql, :insert_sql,
|
||||
:before_add, :after_add, :before_remove, :after_remove,
|
||||
:extend, :readonly
|
||||
:extend, :readonly,
|
||||
:validate
|
||||
)
|
||||
|
||||
options[:extend] = create_extension_modules(association_id, extension, options[:extend])
|
||||
@@ -1638,7 +1646,9 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def join_for_table_name(table_name)
|
||||
@joins.select{|j|j.aliased_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first rescue nil
|
||||
join = (@joins.select{|j|j.aliased_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first) rescue nil
|
||||
return join unless join.nil?
|
||||
@joins.select{|j|j.is_a?(JoinAssociation) && j.aliased_join_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first rescue nil
|
||||
end
|
||||
|
||||
def joins_for_table_name(table_name)
|
||||
|
||||
@@ -1903,10 +1903,12 @@ module ActiveRecord #:nodoc:
|
||||
# MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
|
||||
def compute_type(type_name)
|
||||
modularized_name = type_name_with_module(type_name)
|
||||
begin
|
||||
class_eval(modularized_name, __FILE__, __LINE__)
|
||||
rescue NameError
|
||||
class_eval(type_name, __FILE__, __LINE__)
|
||||
silence_warnings do
|
||||
begin
|
||||
class_eval(modularized_name, __FILE__, __LINE__)
|
||||
rescue NameError
|
||||
class_eval(type_name, __FILE__, __LINE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2064,13 +2066,18 @@ module ActiveRecord #:nodoc:
|
||||
end
|
||||
|
||||
def expand_range_bind_variables(bind_vars) #:nodoc:
|
||||
bind_vars.sum do |var|
|
||||
expanded = []
|
||||
|
||||
bind_vars.each do |var|
|
||||
if var.is_a?(Range)
|
||||
[var.first, var.last]
|
||||
expanded << var.first
|
||||
expanded << var.last
|
||||
else
|
||||
[var]
|
||||
expanded << var
|
||||
end
|
||||
end
|
||||
|
||||
expanded
|
||||
end
|
||||
|
||||
def quote_bound_value(value) #:nodoc:
|
||||
@@ -2247,12 +2254,12 @@ module ActiveRecord #:nodoc:
|
||||
end
|
||||
end
|
||||
|
||||
# Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records.
|
||||
# Note: This method is overwritten by the Validation module that'll make sure that updates made with this method
|
||||
# aren't subjected to validation checks. Hence, attributes can be updated even if the full object isn't valid.
|
||||
# Updates a single attribute and saves the record without going through the normal validation procedure.
|
||||
# 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)
|
||||
save
|
||||
save(false)
|
||||
end
|
||||
|
||||
# Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module ActiveRecord
|
||||
module Calculations #:nodoc:
|
||||
CALCULATIONS_OPTIONS = [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include]
|
||||
CALCULATIONS_OPTIONS = [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include, :from]
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
@@ -27,6 +27,8 @@ module ActiveRecord
|
||||
# * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not
|
||||
# include the joined columns.
|
||||
# * <tt>:distinct</tt>: Set this to true to make this a distinct calculation, such as SELECT COUNT(DISTINCT posts.id) ...
|
||||
# * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
|
||||
# of a database view).
|
||||
#
|
||||
# Examples for counting all:
|
||||
# Person.count # returns the total count of all people
|
||||
@@ -178,8 +180,12 @@ module ActiveRecord
|
||||
sql = "SELECT COUNT(*) AS #{aggregate_alias}" if use_workaround
|
||||
|
||||
sql << ", #{options[:group_field]} AS #{options[:group_alias]}" if options[:group]
|
||||
sql << " FROM (SELECT #{distinct}#{column_name}" if use_workaround
|
||||
sql << " FROM #{connection.quote_table_name(table_name)} "
|
||||
if options[:from]
|
||||
sql << " FROM #{options[:from]} "
|
||||
else
|
||||
sql << " FROM (SELECT #{distinct}#{column_name}" if use_workaround
|
||||
sql << " FROM #{connection.quote_table_name(table_name)} "
|
||||
end
|
||||
if merged_includes.any?
|
||||
join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, merged_includes, options[:joins])
|
||||
sql << join_dependency.join_associations.collect{|join| join.association_join }.join
|
||||
|
||||
@@ -356,7 +356,7 @@ module ActiveRecord
|
||||
|
||||
def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
|
||||
if native = native_database_types[type]
|
||||
column_type_sql = native.is_a?(Hash) ? native[:name] : native
|
||||
column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
|
||||
|
||||
if type == :decimal # ignore limit, use precision and scale
|
||||
scale ||= native[:scale]
|
||||
@@ -371,7 +371,7 @@ module ActiveRecord
|
||||
raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale if specified"
|
||||
end
|
||||
|
||||
elsif limit ||= native.is_a?(Hash) && native[:limit]
|
||||
elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
|
||||
column_type_sql << "(#{limit})"
|
||||
end
|
||||
|
||||
|
||||
@@ -42,30 +42,6 @@ end
|
||||
|
||||
module ActiveRecord
|
||||
class Base
|
||||
def self.require_mysql
|
||||
# Include the MySQL driver if one hasn't already been loaded
|
||||
unless defined? Mysql
|
||||
begin
|
||||
require_library_or_gem 'mysql'
|
||||
rescue LoadError => cannot_require_mysql
|
||||
# Use the bundled Ruby/MySQL driver if no driver is already in place
|
||||
begin
|
||||
ActiveRecord::Base.logger.info(
|
||||
"WARNING: You're using the Ruby-based MySQL library that ships with Rails. This library is not suited for production. " +
|
||||
"Please install the C-based MySQL library instead (gem install mysql)."
|
||||
) if ActiveRecord::Base.logger
|
||||
|
||||
require 'active_record/vendor/mysql'
|
||||
rescue LoadError
|
||||
raise cannot_require_mysql
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Define Mysql::Result.all_hashes
|
||||
MysqlCompat.define_all_hashes_method!
|
||||
end
|
||||
|
||||
# Establishes a connection to the database that's used by all Active Record objects.
|
||||
def self.mysql_connection(config) # :nodoc:
|
||||
config = config.symbolize_keys
|
||||
@@ -81,7 +57,17 @@ module ActiveRecord
|
||||
raise ArgumentError, "No database specified. Missing argument: database."
|
||||
end
|
||||
|
||||
require_mysql
|
||||
# Require the MySQL driver and define Mysql::Result.all_hashes
|
||||
unless defined? Mysql
|
||||
begin
|
||||
require_library_or_gem('mysql')
|
||||
rescue LoadError
|
||||
$stderr.puts '!!! The bundled mysql.rb driver has been removed from Rails 2.2. Please install the mysql gem and try again: gem install mysql.'
|
||||
raise
|
||||
end
|
||||
end
|
||||
MysqlCompat.define_all_hashes_method!
|
||||
|
||||
mysql = Mysql.init
|
||||
mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslkey]
|
||||
|
||||
@@ -165,8 +151,10 @@ module ActiveRecord
|
||||
#
|
||||
# ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false
|
||||
class MysqlAdapter < AbstractAdapter
|
||||
@@emulate_booleans = true
|
||||
cattr_accessor :emulate_booleans
|
||||
self.emulate_booleans = true
|
||||
|
||||
ADAPTER_NAME = 'MySQL'.freeze
|
||||
|
||||
LOST_CONNECTION_ERROR_MESSAGES = [
|
||||
"Server shutdown in progress",
|
||||
@@ -174,7 +162,22 @@ module ActiveRecord
|
||||
"Lost connection to MySQL server during query",
|
||||
"MySQL server has gone away" ]
|
||||
|
||||
QUOTED_TRUE, QUOTED_FALSE = '1', '0'
|
||||
QUOTED_TRUE, QUOTED_FALSE = '1'.freeze, '0'.freeze
|
||||
|
||||
NATIVE_DATABASE_TYPES = {
|
||||
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY".freeze,
|
||||
:string => { :name => "varchar", :limit => 255 },
|
||||
:text => { :name => "text" },
|
||||
:integer => { :name => "int"},
|
||||
:float => { :name => "float" },
|
||||
:decimal => { :name => "decimal" },
|
||||
:datetime => { :name => "datetime" },
|
||||
:timestamp => { :name => "datetime" },
|
||||
:time => { :name => "time" },
|
||||
:date => { :name => "date" },
|
||||
:binary => { :name => "blob" },
|
||||
:boolean => { :name => "tinyint", :limit => 1 }
|
||||
}
|
||||
|
||||
def initialize(connection, logger, connection_options, config)
|
||||
super(connection, logger)
|
||||
@@ -184,7 +187,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def adapter_name #:nodoc:
|
||||
'MySQL'
|
||||
ADAPTER_NAME
|
||||
end
|
||||
|
||||
def supports_migrations? #:nodoc:
|
||||
@@ -192,20 +195,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def native_database_types #:nodoc:
|
||||
{
|
||||
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
|
||||
:string => { :name => "varchar", :limit => 255 },
|
||||
:text => { :name => "text" },
|
||||
:integer => { :name => "int"},
|
||||
:float => { :name => "float" },
|
||||
:decimal => { :name => "decimal" },
|
||||
:datetime => { :name => "datetime" },
|
||||
:timestamp => { :name => "datetime" },
|
||||
:time => { :name => "time" },
|
||||
:date => { :name => "date" },
|
||||
:binary => { :name => "blob" },
|
||||
:boolean => { :name => "tinyint", :limit => 1 }
|
||||
}
|
||||
NATIVE_DATABASE_TYPES
|
||||
end
|
||||
|
||||
|
||||
@@ -498,12 +488,17 @@ module ActiveRecord
|
||||
|
||||
private
|
||||
def connect
|
||||
@connection.reconnect = true if @connection.respond_to?(:reconnect=)
|
||||
|
||||
encoding = @config[:encoding]
|
||||
if encoding
|
||||
@connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
|
||||
end
|
||||
|
||||
@connection.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher]) if @config[:sslkey]
|
||||
|
||||
@connection.real_connect(*@connection_options)
|
||||
|
||||
execute("SET NAMES '#{encoding}'") if encoding
|
||||
|
||||
# By default, MySQL 'where id is null' selects the last inserted id.
|
||||
|
||||
@@ -238,9 +238,26 @@ module ActiveRecord
|
||||
# * <tt>:min_messages</tt> - An optional client min messages that is used in a <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
|
||||
# * <tt>:allow_concurrency</tt> - If true, use async query methods so Ruby threads don't deadlock; otherwise, use blocking query methods.
|
||||
class PostgreSQLAdapter < AbstractAdapter
|
||||
ADAPTER_NAME = 'PostgreSQL'.freeze
|
||||
|
||||
NATIVE_DATABASE_TYPES = {
|
||||
:primary_key => "serial primary key".freeze,
|
||||
:string => { :name => "character varying", :limit => 255 },
|
||||
:text => { :name => "text" },
|
||||
:integer => { :name => "integer" },
|
||||
:float => { :name => "float" },
|
||||
:decimal => { :name => "decimal" },
|
||||
:datetime => { :name => "timestamp" },
|
||||
:timestamp => { :name => "timestamp" },
|
||||
:time => { :name => "time" },
|
||||
:date => { :name => "date" },
|
||||
:binary => { :name => "bytea" },
|
||||
:boolean => { :name => "boolean" }
|
||||
}
|
||||
|
||||
# Returns 'PostgreSQL' as adapter name for identification purposes.
|
||||
def adapter_name
|
||||
'PostgreSQL'
|
||||
ADAPTER_NAME
|
||||
end
|
||||
|
||||
# Initializes and connects a PostgreSQL adapter.
|
||||
@@ -282,20 +299,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def native_database_types #:nodoc:
|
||||
{
|
||||
:primary_key => "serial primary key",
|
||||
:string => { :name => "character varying", :limit => 255 },
|
||||
:text => { :name => "text" },
|
||||
:integer => { :name => "integer" },
|
||||
:float => { :name => "float" },
|
||||
:decimal => { :name => "decimal" },
|
||||
:datetime => { :name => "timestamp" },
|
||||
:timestamp => { :name => "timestamp" },
|
||||
:time => { :name => "time" },
|
||||
:date => { :name => "date" },
|
||||
:binary => { :name => "bytea" },
|
||||
:boolean => { :name => "boolean" }
|
||||
}
|
||||
NATIVE_DATABASE_TYPES
|
||||
end
|
||||
|
||||
# Does PostgreSQL support migrations?
|
||||
@@ -319,6 +323,15 @@ module ActiveRecord
|
||||
has_support
|
||||
end
|
||||
|
||||
def supports_insert_with_returning?
|
||||
unless defined? @supports_insert_with_returning
|
||||
@supports_insert_with_returning =
|
||||
@connection.respond_to?(:server_version) &&
|
||||
@connection.server_version >= 80200
|
||||
end
|
||||
@supports_insert_with_returning
|
||||
end
|
||||
|
||||
# Returns the configured supported identifier length supported by PostgreSQL,
|
||||
# or report the default of 63 on PostgreSQL 7.x.
|
||||
def table_alias_length
|
||||
@@ -411,8 +424,34 @@ module ActiveRecord
|
||||
|
||||
# Executes an INSERT query and returns the new record's ID
|
||||
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
||||
# Extract the table from the insert sql. Yuck.
|
||||
table = sql.split(" ", 4)[2].gsub('"', '')
|
||||
super || pk && last_insert_id(table, sequence_name || default_sequence_name(table, pk))
|
||||
|
||||
# Try an insert with 'returning id' if available (PG >= 8.2)
|
||||
if supports_insert_with_returning?
|
||||
pk, sequence_name = *pk_and_sequence_for(table) unless pk
|
||||
if pk
|
||||
id = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
|
||||
clear_query_cache
|
||||
return id
|
||||
end
|
||||
end
|
||||
|
||||
# Otherwise, insert then grab last_insert_id.
|
||||
if insert_id = super
|
||||
insert_id
|
||||
else
|
||||
# If neither pk nor sequence name is given, look them up.
|
||||
unless pk || sequence_name
|
||||
pk, sequence_name = *pk_and_sequence_for(table)
|
||||
end
|
||||
|
||||
# If a pk is given, fallback to default sequence name.
|
||||
# Don't fetch last insert id for a table without a pk.
|
||||
if pk && sequence_name ||= default_sequence_name(table, pk)
|
||||
last_insert_id(table, sequence_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# create a 2D array representing the result set
|
||||
@@ -506,7 +545,7 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
execute "CREATE DATABASE #{name}#{option_string}"
|
||||
execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
|
||||
end
|
||||
|
||||
# Drops a PostgreSQL database
|
||||
@@ -514,7 +553,7 @@ module ActiveRecord
|
||||
# Example:
|
||||
# drop_database 'matt_development'
|
||||
def drop_database(name) #:nodoc:
|
||||
execute "DROP DATABASE IF EXISTS #{name}"
|
||||
execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
|
||||
end
|
||||
|
||||
|
||||
@@ -676,7 +715,7 @@ module ActiveRecord
|
||||
|
||||
# Renames a table.
|
||||
def rename_table(name, new_name)
|
||||
execute "ALTER TABLE #{name} RENAME TO #{new_name}"
|
||||
execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
|
||||
end
|
||||
|
||||
# Adds a new column to the named table.
|
||||
|
||||
@@ -547,7 +547,7 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
|
||||
@connection, @table_name, @fixture_path, @file_filter = connection, table_name, fixture_path, file_filter
|
||||
@class_name = class_name ||
|
||||
(ActiveRecord::Base.pluralize_table_names ? @table_name.singularize.camelize : @table_name.camelize)
|
||||
@table_name = ActiveRecord::Base.table_name_prefix + @table_name + ActiveRecord::Base.table_name_suffix
|
||||
@table_name = "#{ActiveRecord::Base.table_name_prefix}#{@table_name}#{ActiveRecord::Base.table_name_suffix}"
|
||||
@table_name = class_name.table_name if class_name.respond_to?(:table_name)
|
||||
@connection = class_name.connection if class_name.respond_to?(:connection)
|
||||
read_fixture_files
|
||||
|
||||
@@ -277,7 +277,6 @@ module ActiveRecord
|
||||
base.class_eval do
|
||||
alias_method_chain :save, :validation
|
||||
alias_method_chain :save!, :validation
|
||||
alias_method_chain :update_attribute, :validation_skipping
|
||||
end
|
||||
|
||||
base.send :include, ActiveSupport::Callbacks
|
||||
@@ -914,14 +913,6 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Updates a single attribute and saves the record without going through the normal validation procedure.
|
||||
# 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_with_validation_skipping(name, value)
|
||||
send(name.to_s + '=', value)
|
||||
save(false)
|
||||
end
|
||||
|
||||
# Runs +validate+ and +validate_on_create+ or +validate_on_update+ and returns true if no errors were added otherwise false.
|
||||
def valid?
|
||||
errors.clear
|
||||
|
||||
362
activerecord/lib/active_record/vendor/db2.rb
vendored
362
activerecord/lib/active_record/vendor/db2.rb
vendored
@@ -1,362 +0,0 @@
|
||||
require 'db2/db2cli.rb'
|
||||
|
||||
module DB2
|
||||
module DB2Util
|
||||
include DB2CLI
|
||||
|
||||
def free() SQLFreeHandle(@handle_type, @handle); end
|
||||
def handle() @handle; end
|
||||
|
||||
def check_rc(rc)
|
||||
if ![SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA_FOUND].include?(rc)
|
||||
rec = 1
|
||||
msg = ''
|
||||
loop do
|
||||
a = SQLGetDiagRec(@handle_type, @handle, rec, 500)
|
||||
break if a[0] != SQL_SUCCESS
|
||||
msg << a[3] if !a[3].nil? and a[3] != '' # Create message.
|
||||
rec += 1
|
||||
end
|
||||
raise "DB2 error: #{msg}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Environment
|
||||
include DB2Util
|
||||
|
||||
def initialize
|
||||
@handle_type = SQL_HANDLE_ENV
|
||||
rc, @handle = SQLAllocHandle(@handle_type, SQL_NULL_HANDLE)
|
||||
check_rc(rc)
|
||||
end
|
||||
|
||||
def data_sources(buffer_length = 1024)
|
||||
retval = []
|
||||
max_buffer_length = buffer_length
|
||||
|
||||
a = SQLDataSources(@handle, SQL_FETCH_FIRST, SQL_MAX_DSN_LENGTH + 1, buffer_length)
|
||||
retval << [a[1], a[3]]
|
||||
max_buffer_length = [max_buffer_length, a[4]].max
|
||||
|
||||
loop do
|
||||
a = SQLDataSources(@handle, SQL_FETCH_NEXT, SQL_MAX_DSN_LENGTH + 1, buffer_length)
|
||||
break if a[0] == SQL_NO_DATA_FOUND
|
||||
|
||||
retval << [a[1], a[3]]
|
||||
max_buffer_length = [max_buffer_length, a[4]].max
|
||||
end
|
||||
|
||||
if max_buffer_length > buffer_length
|
||||
get_data_sources(max_buffer_length)
|
||||
else
|
||||
retval
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Connection
|
||||
include DB2Util
|
||||
|
||||
def initialize(environment)
|
||||
@env = environment
|
||||
@handle_type = SQL_HANDLE_DBC
|
||||
rc, @handle = SQLAllocHandle(@handle_type, @env.handle)
|
||||
check_rc(rc)
|
||||
end
|
||||
|
||||
def connect(server_name, user_name = '', auth = '')
|
||||
check_rc(SQLConnect(@handle, server_name, user_name.to_s, auth.to_s))
|
||||
end
|
||||
|
||||
def set_connect_attr(attr, value)
|
||||
value += "\0" if value.class == String
|
||||
check_rc(SQLSetConnectAttr(@handle, attr, value))
|
||||
end
|
||||
|
||||
def set_auto_commit_on
|
||||
set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON)
|
||||
end
|
||||
|
||||
def set_auto_commit_off
|
||||
set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF)
|
||||
end
|
||||
|
||||
def disconnect
|
||||
check_rc(SQLDisconnect(@handle))
|
||||
end
|
||||
|
||||
def rollback
|
||||
check_rc(SQLEndTran(@handle_type, @handle, SQL_ROLLBACK))
|
||||
end
|
||||
|
||||
def commit
|
||||
check_rc(SQLEndTran(@handle_type, @handle, SQL_COMMIT))
|
||||
end
|
||||
end
|
||||
|
||||
class Statement
|
||||
include DB2Util
|
||||
|
||||
def initialize(connection)
|
||||
@conn = connection
|
||||
@handle_type = SQL_HANDLE_STMT
|
||||
@parms = [] #yun
|
||||
@sql = '' #yun
|
||||
@numParms = 0 #yun
|
||||
@prepared = false #yun
|
||||
@parmArray = [] #yun. attributes of the parameter markers
|
||||
rc, @handle = SQLAllocHandle(@handle_type, @conn.handle)
|
||||
check_rc(rc)
|
||||
end
|
||||
|
||||
def columns(table_name, schema_name = '%')
|
||||
check_rc(SQLColumns(@handle, '', schema_name.upcase, table_name.upcase, '%'))
|
||||
fetch_all
|
||||
end
|
||||
|
||||
def tables(schema_name = '%')
|
||||
check_rc(SQLTables(@handle, '', schema_name.upcase, '%', 'TABLE'))
|
||||
fetch_all
|
||||
end
|
||||
|
||||
def indexes(table_name, schema_name = '')
|
||||
check_rc(SQLStatistics(@handle, '', schema_name.upcase, table_name.upcase, SQL_INDEX_ALL, SQL_ENSURE))
|
||||
fetch_all
|
||||
end
|
||||
|
||||
def prepare(sql)
|
||||
@sql = sql
|
||||
check_rc(SQLPrepare(@handle, sql))
|
||||
rc, @numParms = SQLNumParams(@handle) #number of question marks
|
||||
check_rc(rc)
|
||||
#--------------------------------------------------------------------------
|
||||
# parameter attributes are stored in instance variable @parmArray so that
|
||||
# they are available when execute method is called.
|
||||
#--------------------------------------------------------------------------
|
||||
if @numParms > 0 # get parameter marker attributes
|
||||
1.upto(@numParms) do |i| # parameter number starts from 1
|
||||
rc, type, size, decimalDigits = SQLDescribeParam(@handle, i)
|
||||
check_rc(rc)
|
||||
@parmArray << Parameter.new(type, size, decimalDigits)
|
||||
end
|
||||
end
|
||||
@prepared = true
|
||||
self
|
||||
end
|
||||
|
||||
def execute(*parms)
|
||||
raise "The statement was not prepared" if @prepared == false
|
||||
|
||||
if parms.size == 1 and parms[0].class == Array
|
||||
parms = parms[0]
|
||||
end
|
||||
|
||||
if @numParms != parms.size
|
||||
raise "Number of parameters supplied does not match with the SQL statement"
|
||||
end
|
||||
|
||||
if @numParms > 0 #need to bind parameters
|
||||
#--------------------------------------------------------------------
|
||||
#calling bindParms may not be safe. Look comment below.
|
||||
#--------------------------------------------------------------------
|
||||
#bindParms(parms)
|
||||
|
||||
valueArray = []
|
||||
1.upto(@numParms) do |i| # parameter number starts from 1
|
||||
type = @parmArray[i - 1].class
|
||||
size = @parmArray[i - 1].size
|
||||
decimalDigits = @parmArray[i - 1].decimalDigits
|
||||
|
||||
if parms[i - 1].class == String
|
||||
valueArray << parms[i - 1]
|
||||
else
|
||||
valueArray << parms[i - 1].to_s
|
||||
end
|
||||
|
||||
rc = SQLBindParameter(@handle, i, type, size, decimalDigits, valueArray[i - 1])
|
||||
check_rc(rc)
|
||||
end
|
||||
end
|
||||
|
||||
check_rc(SQLExecute(@handle))
|
||||
|
||||
if @numParms != 0
|
||||
check_rc(SQLFreeStmt(@handle, SQL_RESET_PARAMS)) # Reset parameters
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# The last argument(value) to SQLBindParameter is a deferred argument, that is,
|
||||
# it should be available when SQLExecute is called. Even though "value" is
|
||||
# local to bindParms method, it seems that it is available when SQLExecute
|
||||
# is called. I am not sure whether it would still work if garbage collection
|
||||
# is done between bindParms call and SQLExecute call inside the execute method
|
||||
# above.
|
||||
#-------------------------------------------------------------------------------
|
||||
def bindParms(parms) # This is the real thing. It uses SQLBindParms
|
||||
1.upto(@numParms) do |i| # parameter number starts from 1
|
||||
rc, dataType, parmSize, decimalDigits = SQLDescribeParam(@handle, i)
|
||||
check_rc(rc)
|
||||
if parms[i - 1].class == String
|
||||
value = parms[i - 1]
|
||||
else
|
||||
value = parms[i - 1].to_s
|
||||
end
|
||||
rc = SQLBindParameter(@handle, i, dataType, parmSize, decimalDigits, value)
|
||||
check_rc(rc)
|
||||
end
|
||||
end
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# bind method does not use DB2's SQLBindParams, but replaces "?" in the
|
||||
# SQL statement with the value before passing the SQL statement to DB2.
|
||||
# It is not efficient and can handle only strings since it puts everything in
|
||||
# quotes.
|
||||
#------------------------------------------------------------------------------
|
||||
def bind(sql, args) #does not use SQLBindParams
|
||||
arg_index = 0
|
||||
result = ""
|
||||
tokens(sql).each do |part|
|
||||
case part
|
||||
when '?'
|
||||
result << "'" + (args[arg_index]) + "'" #put it into quotes
|
||||
arg_index += 1
|
||||
when '??'
|
||||
result << "?"
|
||||
else
|
||||
result << part
|
||||
end
|
||||
end
|
||||
if arg_index < args.size
|
||||
raise "Too many SQL parameters"
|
||||
elsif arg_index > args.size
|
||||
raise "Not enough SQL parameters"
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
## Break the sql string into parts.
|
||||
#
|
||||
# This is NOT a full lexer for SQL. It just breaks up the SQL
|
||||
# string enough so that question marks, double question marks and
|
||||
# quoted strings are separated. This is used when binding
|
||||
# arguments to "?" in the SQL string. Note: comments are not
|
||||
# handled.
|
||||
#
|
||||
def tokens(sql)
|
||||
toks = sql.scan(/('([^'\\]|''|\\.)*'|"([^"\\]|""|\\.)*"|\?\??|[^'"?]+)/)
|
||||
toks.collect { |t| t[0] }
|
||||
end
|
||||
|
||||
def exec_direct(sql)
|
||||
check_rc(SQLExecDirect(@handle, sql))
|
||||
self
|
||||
end
|
||||
|
||||
def set_cursor_name(name)
|
||||
check_rc(SQLSetCursorName(@handle, name))
|
||||
self
|
||||
end
|
||||
|
||||
def get_cursor_name
|
||||
rc, name = SQLGetCursorName(@handle)
|
||||
check_rc(rc)
|
||||
name
|
||||
end
|
||||
|
||||
def row_count
|
||||
rc, rowcount = SQLRowCount(@handle)
|
||||
check_rc(rc)
|
||||
rowcount
|
||||
end
|
||||
|
||||
def num_result_cols
|
||||
rc, cols = SQLNumResultCols(@handle)
|
||||
check_rc(rc)
|
||||
cols
|
||||
end
|
||||
|
||||
def fetch_all
|
||||
if block_given?
|
||||
while row = fetch do
|
||||
yield row
|
||||
end
|
||||
else
|
||||
res = []
|
||||
while row = fetch do
|
||||
res << row
|
||||
end
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
def fetch
|
||||
cols = get_col_desc
|
||||
rc = SQLFetch(@handle)
|
||||
if rc == SQL_NO_DATA_FOUND
|
||||
SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor
|
||||
SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters
|
||||
return nil
|
||||
end
|
||||
raise "ERROR" unless rc == SQL_SUCCESS
|
||||
|
||||
retval = []
|
||||
cols.each_with_index do |c, i|
|
||||
rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2]
|
||||
retval << adjust_content(content)
|
||||
end
|
||||
retval
|
||||
end
|
||||
|
||||
def fetch_as_hash
|
||||
cols = get_col_desc
|
||||
rc = SQLFetch(@handle)
|
||||
if rc == SQL_NO_DATA_FOUND
|
||||
SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor
|
||||
SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters
|
||||
return nil
|
||||
end
|
||||
raise "ERROR" unless rc == SQL_SUCCESS
|
||||
|
||||
retval = {}
|
||||
cols.each_with_index do |c, i|
|
||||
rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2]
|
||||
retval[c[0]] = adjust_content(content)
|
||||
end
|
||||
retval
|
||||
end
|
||||
|
||||
def get_col_desc
|
||||
rc, nr_cols = SQLNumResultCols(@handle)
|
||||
cols = (1..nr_cols).collect do |c|
|
||||
rc, name, bl, type, col_sz = SQLDescribeCol(@handle, c, 1024)
|
||||
[name.downcase, type, col_sz]
|
||||
end
|
||||
end
|
||||
|
||||
def adjust_content(c)
|
||||
case c.class.to_s
|
||||
when 'DB2CLI::NullClass'
|
||||
return nil
|
||||
when 'DB2CLI::Time'
|
||||
"%02d:%02d:%02d" % [c.hour, c.minute, c.second]
|
||||
when 'DB2CLI::Date'
|
||||
"%04d-%02d-%02d" % [c.year, c.month, c.day]
|
||||
when 'DB2CLI::Timestamp'
|
||||
"%04d-%02d-%02d %02d:%02d:%02d" % [c.year, c.month, c.day, c.hour, c.minute, c.second]
|
||||
else
|
||||
return c
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Parameter
|
||||
attr_reader :type, :size, :decimalDigits
|
||||
def initialize(type, size, decimalDigits)
|
||||
@type, @size, @decimalDigits = type, size, decimalDigits
|
||||
end
|
||||
end
|
||||
end
|
||||
1214
activerecord/lib/active_record/vendor/mysql.rb
vendored
1214
activerecord/lib/active_record/vendor/mysql.rb
vendored
File diff suppressed because it is too large
Load Diff
@@ -13,8 +13,8 @@ class PostgresqlActiveSchemaTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_create_database_with_encoding
|
||||
assert_equal "CREATE DATABASE matt ENCODING = 'utf8'", create_database(:matt)
|
||||
assert_equal "CREATE DATABASE aimonetti ENCODING = 'latin1'", create_database(:aimonetti, :encoding => :latin1)
|
||||
assert_equal %(CREATE DATABASE "matt" ENCODING = 'utf8'), create_database(:matt)
|
||||
assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -409,4 +409,23 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
||||
sponsor.sponsorable = new_member
|
||||
assert_equal nil, sponsor.sponsorable_id
|
||||
end
|
||||
|
||||
def test_save_fails_for_invalid_belongs_to
|
||||
assert log = AuditLog.create(:developer_id=>0,:message=>"")
|
||||
|
||||
log.developer = Developer.new
|
||||
assert !log.developer.valid?
|
||||
assert !log.valid?
|
||||
assert !log.save
|
||||
assert_equal "is invalid", log.errors.on("developer")
|
||||
end
|
||||
|
||||
def test_save_succeeds_for_invalid_belongs_to_with_validate_false
|
||||
assert log = AuditLog.create(:developer_id=>0,:message=>"")
|
||||
|
||||
log.unvalidated_developer = Developer.new
|
||||
assert !log.unvalidated_developer.valid?
|
||||
assert log.valid?
|
||||
assert log.save
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,11 +14,14 @@ require 'models/job'
|
||||
require 'models/subscriber'
|
||||
require 'models/subscription'
|
||||
require 'models/book'
|
||||
require 'models/developer'
|
||||
require 'models/project'
|
||||
|
||||
class EagerAssociationTest < ActiveRecord::TestCase
|
||||
fixtures :posts, :comments, :authors, :categories, :categories_posts,
|
||||
:companies, :accounts, :tags, :taggings, :people, :readers,
|
||||
:owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books
|
||||
:owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
|
||||
:developers, :projects
|
||||
|
||||
def test_loading_with_one_association
|
||||
posts = Post.find(:all, :include => :comments)
|
||||
@@ -609,4 +612,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
||||
Comment.find :all, :include => :post
|
||||
end
|
||||
end
|
||||
|
||||
def test_conditions_on_join_table_with_include_and_limit
|
||||
assert_equal 3, Developer.find(:all, :include => 'projects', :conditions => 'developers_projects.access_level = 1', :limit => 5).size
|
||||
end
|
||||
|
||||
def test_order_on_join_table_with_include_and_limit
|
||||
assert_equal 5, Developer.find(:all, :include => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).size
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,15 +37,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
||||
end
|
||||
|
||||
def test_counting_with_single_conditions
|
||||
assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
|
||||
assert_equal 1, Firm.find(:first).plain_clients.count(:conditions => ['name=?', "Microsoft"])
|
||||
end
|
||||
|
||||
def test_counting_with_single_hash
|
||||
assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
|
||||
assert_equal 1, Firm.find(:first).plain_clients.count(:conditions => {:name => "Microsoft"})
|
||||
end
|
||||
|
||||
def test_counting_with_column_name_and_hash
|
||||
assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1')
|
||||
assert_equal 2, Firm.find(:first).plain_clients.count(:name)
|
||||
end
|
||||
|
||||
def test_finding
|
||||
@@ -342,6 +342,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
||||
assert new_firm.new_record?
|
||||
end
|
||||
|
||||
def test_invalid_adding_with_validate_false
|
||||
firm = Firm.find(:first)
|
||||
client = Client.new
|
||||
firm.unvalidated_clients_of_firm << Client.new
|
||||
|
||||
assert firm.valid?
|
||||
assert !client.valid?
|
||||
assert firm.save
|
||||
assert client.new_record?
|
||||
end
|
||||
|
||||
def test_build
|
||||
company = companies(:first_firm)
|
||||
new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
|
||||
|
||||
@@ -275,6 +275,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
||||
assert_equal "is invalid", firm.errors.on("account")
|
||||
end
|
||||
|
||||
|
||||
def test_save_succeeds_for_invalid_has_one_with_validate_false
|
||||
firm = Firm.find(:first)
|
||||
assert firm.valid?
|
||||
|
||||
firm.unvalidated_account = Account.new
|
||||
|
||||
assert !firm.unvalidated_account.valid?
|
||||
assert firm.valid?
|
||||
assert firm.save
|
||||
end
|
||||
|
||||
def test_assignment_before_either_saved
|
||||
firm = Firm.new("name" => "GlobalMegaCorp")
|
||||
firm.account = a = Account.new("credit_limit" => 1000)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require "cases/helper"
|
||||
require 'models/company'
|
||||
require 'models/topic'
|
||||
require 'models/edge'
|
||||
|
||||
Company.has_many :accounts
|
||||
|
||||
@@ -274,4 +275,49 @@ class CalculationsTest < ActiveRecord::TestCase
|
||||
def test_should_sum_expression
|
||||
assert_equal 636, Account.sum("2 * credit_limit")
|
||||
end
|
||||
|
||||
def test_count_with_from_option
|
||||
assert_equal Company.count(:all), Company.count(:all, :from => 'companies')
|
||||
assert_equal Account.count(:all, :conditions => "credit_limit = 50"),
|
||||
Account.count(:all, :from => 'accounts', :conditions => "credit_limit = 50")
|
||||
assert_equal Company.count(:type, :conditions => {:type => "Firm"}),
|
||||
Company.count(:type, :conditions => {:type => "Firm"}, :from => 'companies')
|
||||
end
|
||||
|
||||
def test_sum_with_from_option
|
||||
assert_equal Account.sum(:credit_limit), Account.sum(:credit_limit, :from => 'accounts')
|
||||
assert_equal Account.sum(:credit_limit, :conditions => "credit_limit > 50"),
|
||||
Account.sum(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
|
||||
end
|
||||
|
||||
def test_average_with_from_option
|
||||
assert_equal Account.average(:credit_limit), Account.average(:credit_limit, :from => 'accounts')
|
||||
assert_equal Account.average(:credit_limit, :conditions => "credit_limit > 50"),
|
||||
Account.average(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
|
||||
end
|
||||
|
||||
def test_minimum_with_from_option
|
||||
assert_equal Account.minimum(:credit_limit), Account.minimum(:credit_limit, :from => 'accounts')
|
||||
assert_equal Account.minimum(:credit_limit, :conditions => "credit_limit > 50"),
|
||||
Account.minimum(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
|
||||
end
|
||||
|
||||
def test_maximum_with_from_option
|
||||
assert_equal Account.maximum(:credit_limit), Account.maximum(:credit_limit, :from => 'accounts')
|
||||
assert_equal Account.maximum(:credit_limit, :conditions => "credit_limit > 50"),
|
||||
Account.maximum(:credit_limit, :from => 'accounts', :conditions => "credit_limit > 50")
|
||||
end
|
||||
|
||||
def test_from_option_with_specified_index
|
||||
if Edge.connection.adapter_name == 'MySQL'
|
||||
assert_equal Edge.count(:all), Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)')
|
||||
assert_equal Edge.count(:all, :conditions => 'sink_id < 5'),
|
||||
Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)', :conditions => 'sink_id < 5')
|
||||
end
|
||||
end
|
||||
|
||||
def test_from_option_with_table_different_than_class
|
||||
assert_equal Account.count(:all), Company.count(:all, :from => 'accounts')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
12
activerecord/test/cases/database_statements_test.rb
Normal file
12
activerecord/test/cases/database_statements_test.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require "cases/helper"
|
||||
|
||||
class DatabaseStatementsTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
@connection = ActiveRecord::Base.connection
|
||||
end
|
||||
|
||||
def test_insert_should_return_the_inserted_id
|
||||
id = @connection.insert("INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)")
|
||||
assert_not_nil id
|
||||
end
|
||||
end
|
||||
@@ -160,9 +160,9 @@ class ReflectionTest < ActiveRecord::TestCase
|
||||
|
||||
def test_reflection_of_all_associations
|
||||
# FIXME these assertions bust a lot
|
||||
assert_equal 20, Firm.reflect_on_all_associations.size
|
||||
assert_equal 16, Firm.reflect_on_all_associations(:has_many).size
|
||||
assert_equal 4, Firm.reflect_on_all_associations(:has_one).size
|
||||
assert_equal 22, Firm.reflect_on_all_associations.size
|
||||
assert_equal 17, Firm.reflect_on_all_associations(:has_many).size
|
||||
assert_equal 5, Firm.reflect_on_all_associations(:has_one).size
|
||||
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
|
||||
end
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ class Firm < Company
|
||||
"AND (#{QUOTED_TYPE} = 'Client' OR #{QUOTED_TYPE} = 'SpecialClient' OR #{QUOTED_TYPE} = 'VerySpecialClient' )"
|
||||
has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC"
|
||||
has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id"
|
||||
has_many :unvalidated_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :validate => false
|
||||
has_many :dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :destroy
|
||||
has_many :exclusively_dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all
|
||||
has_many :limited_clients, :class_name => "Client", :order => "id", :limit => 1
|
||||
@@ -46,7 +47,8 @@ class Firm < Company
|
||||
has_many :plain_clients, :class_name => 'Client'
|
||||
has_many :readonly_clients, :class_name => 'Client', :readonly => true
|
||||
|
||||
has_one :account, :foreign_key => "firm_id", :dependent => :destroy
|
||||
has_one :account, :foreign_key => "firm_id", :dependent => :destroy, :validate => true
|
||||
has_one :unvalidated_account, :foreign_key => "firm_id", :class_name => 'Account', :validate => false
|
||||
has_one :account_with_select, :foreign_key => "firm_id", :select => "id, firm_id", :class_name=>'Account'
|
||||
has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true
|
||||
end
|
||||
|
||||
@@ -56,7 +56,8 @@ class Developer < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class AuditLog < ActiveRecord::Base
|
||||
belongs_to :developer
|
||||
belongs_to :developer, :validate => true
|
||||
belongs_to :unvalidated_developer, :class_name => 'Developer'
|
||||
end
|
||||
|
||||
DeveloperSalary = Struct.new(:amount)
|
||||
|
||||
@@ -988,7 +988,11 @@ module ActiveResource
|
||||
self.class.const_get(resource_name)
|
||||
end
|
||||
rescue NameError
|
||||
resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base))
|
||||
if self.class.const_defined?(resource_name)
|
||||
resource = self.class.const_get(resource_name)
|
||||
else
|
||||
resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base))
|
||||
end
|
||||
resource.prefix = self.class.prefix
|
||||
resource.site = self.class.site
|
||||
resource
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'abstract_unit'
|
||||
require "fixtures/person"
|
||||
require "fixtures/customer"
|
||||
require "fixtures/street_address"
|
||||
require "fixtures/beast"
|
||||
|
||||
@@ -15,6 +16,37 @@ class BaseTest < Test::Unit::TestCase
|
||||
@people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
|
||||
@addresses = [{ :id => 1, :street => '12345 Street' }].to_xml(:root => 'addresses')
|
||||
|
||||
# - deep nested resource -
|
||||
# - Luis (Customer)
|
||||
# - JK (Customer::Friend)
|
||||
# - Mateo (Customer::Friend::Brother)
|
||||
# - Edith (Customer::Friend::Brother::Child)
|
||||
# - Martha (Customer::Friend::Brother::Child)
|
||||
# - Felipe (Customer::Friend::Brother)
|
||||
# - Bryan (Customer::Friend::Brother::Child)
|
||||
# - Luke (Customer::Friend::Brother::Child)
|
||||
# - Eduardo (Customer::Friend)
|
||||
# - Sebas (Customer::Friend::Brother)
|
||||
# - Andres (Customer::Friend::Brother::Child)
|
||||
# - Jorge (Customer::Friend::Brother::Child)
|
||||
# - Elsa (Customer::Friend::Brother)
|
||||
# - Natacha (Customer::Friend::Brother::Child)
|
||||
# - Milena (Customer::Friend::Brother)
|
||||
#
|
||||
@luis = {:id => 1, :name => 'Luis',
|
||||
:friends => [{:name => 'JK',
|
||||
:brothers => [{:name => 'Mateo',
|
||||
:children => [{:name => 'Edith'},{:name => 'Martha'}]},
|
||||
{:name => 'Felipe',
|
||||
:children => [{:name => 'Bryan'},{:name => 'Luke'}]}]},
|
||||
{:name => 'Eduardo',
|
||||
:brothers => [{:name => 'Sebas',
|
||||
:children => [{:name => 'Andres'},{:name => 'Jorge'}]},
|
||||
{:name => 'Elsa',
|
||||
:children => [{:name => 'Natacha'}]},
|
||||
{:name => 'Milena',
|
||||
:children => []}]}]}.to_xml(:root => 'customer')
|
||||
|
||||
ActiveResource::HttpMock.respond_to do |mock|
|
||||
mock.get "/people/1.xml", {}, @matz
|
||||
mock.get "/people/2.xml", {}, @david
|
||||
@@ -46,6 +78,8 @@ class BaseTest < Test::Unit::TestCase
|
||||
mock.head "/people/1/addresses/2.xml", {}, nil, 404
|
||||
mock.head "/people/2/addresses/1.xml", {}, nil, 404
|
||||
mock.head "/people/Greg/addresses/1.xml", {}, nil, 200
|
||||
# customer
|
||||
mock.get "/customers/1.xml", {}, @luis
|
||||
end
|
||||
|
||||
Person.user = nil
|
||||
@@ -788,4 +822,18 @@ class BaseTest < Test::Unit::TestCase
|
||||
matz = Person.find(1)
|
||||
assert_equal '1', matz.to_param
|
||||
end
|
||||
|
||||
def test_parse_deep_nested_resources
|
||||
luis = Customer.find(1)
|
||||
assert_kind_of Customer, luis
|
||||
luis.friends.each do |friend|
|
||||
assert_kind_of Customer::Friend, friend
|
||||
friend.brothers.each do |brother|
|
||||
assert_kind_of Customer::Friend::Brother, brother
|
||||
brother.children.each do |child|
|
||||
assert_kind_of Customer::Friend::Brother::Child, child
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
3
activeresource/test/fixtures/customer.rb
vendored
Normal file
3
activeresource/test/fixtures/customer.rb
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
class Customer < ActiveResource::Base
|
||||
self.site = "http://37s.sunrise.i:3000"
|
||||
end
|
||||
@@ -7,10 +7,13 @@ module ActiveSupport
|
||||
|
||||
case store
|
||||
when Symbol
|
||||
require "active_support/cache/#{store.to_s}"
|
||||
|
||||
store_class_name = (store == :drb_store ? "DRbStore" : store.to_s.camelize)
|
||||
store_class = ActiveSupport::Cache.const_get(store_class_name)
|
||||
store_class.new(*parameters)
|
||||
when nil
|
||||
require "active_support/cache/memory_store"
|
||||
ActiveSupport::Cache::MemoryStore.new
|
||||
else
|
||||
store
|
||||
@@ -137,9 +140,3 @@ module ActiveSupport
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'active_support/cache/file_store'
|
||||
require 'active_support/cache/memory_store'
|
||||
require 'active_support/cache/drb_store'
|
||||
require 'active_support/cache/mem_cache_store'
|
||||
require 'active_support/cache/compressed_mem_cache_store'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require "active_support/cache/mem_cache_store"
|
||||
|
||||
module ActiveSupport
|
||||
module Cache
|
||||
class CompressedMemCacheStore < MemCacheStore
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'drb'
|
||||
require 'active_support/cache/memory_store'
|
||||
|
||||
module ActiveSupport
|
||||
module Cache
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/ordered_hash'
|
||||
|
||||
module Enumerable
|
||||
# Ruby 1.8.7 introduces group_by, but the result isn't ordered. Override it.
|
||||
remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
|
||||
@@ -18,10 +20,19 @@ module Enumerable
|
||||
# "2006-02-24 -> Transcript, Transcript"
|
||||
# "2006-02-23 -> Transcript"
|
||||
def group_by
|
||||
inject ActiveSupport::OrderedHash.new do |grouped, element|
|
||||
(grouped[yield(element)] ||= []) << element
|
||||
grouped
|
||||
assoc = ActiveSupport::OrderedHash.new
|
||||
|
||||
each do |element|
|
||||
key = yield(element)
|
||||
|
||||
if assoc.has_key?(key)
|
||||
assoc[key] << element
|
||||
else
|
||||
assoc[key] = [element]
|
||||
end
|
||||
end
|
||||
|
||||
assoc
|
||||
end unless [].respond_to?(:group_by)
|
||||
|
||||
# Calculates a sum from the elements. Examples:
|
||||
|
||||
@@ -10,13 +10,14 @@ module ActiveSupport #:nodoc:
|
||||
module Except
|
||||
# Returns a new hash without the given keys.
|
||||
def except(*keys)
|
||||
rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
|
||||
reject { |key,| rejected.include?(key) }
|
||||
clone.except!(*keys)
|
||||
end
|
||||
|
||||
# Replaces the hash without only the given keys.
|
||||
def except!(*keys)
|
||||
replace(except(*keys))
|
||||
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
|
||||
keys.each { |key| delete(key) }
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
require 'set'
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Hash #:nodoc:
|
||||
@@ -14,9 +12,9 @@ module ActiveSupport #:nodoc:
|
||||
module Slice
|
||||
# Returns a new hash with only the given keys.
|
||||
def slice(*keys)
|
||||
allowed = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
|
||||
keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
|
||||
hash = {}
|
||||
allowed.each { |k| hash[k] = self[k] if has_key?(k) }
|
||||
keys.each { |k| hash[k] = self[k] if has_key?(k) }
|
||||
hash
|
||||
end
|
||||
|
||||
|
||||
@@ -6,3 +6,8 @@ require 'active_support/core_ext/module/delegation'
|
||||
require 'active_support/core_ext/module/introspection'
|
||||
require 'active_support/core_ext/module/loading'
|
||||
require 'active_support/core_ext/module/aliasing'
|
||||
require 'active_support/core_ext/module/model_naming'
|
||||
|
||||
class Module
|
||||
include ActiveSupport::CoreExt::Module::ModelNaming
|
||||
end
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
module ActiveSupport
|
||||
class ModelName < String
|
||||
attr_reader :singular, :plural, :partial_path
|
||||
|
||||
def initialize(name)
|
||||
super
|
||||
@singular = underscore.tr('/', '_').freeze
|
||||
@plural = @singular.pluralize.freeze
|
||||
@partial_path = "#{tableize}/#{demodulize.underscore}".freeze
|
||||
end
|
||||
end
|
||||
|
||||
module CoreExt
|
||||
module Module
|
||||
module ModelNaming
|
||||
def model_name
|
||||
@model_name ||= ModelName.new(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,17 +3,18 @@ class Object
|
||||
Class.remove_class(*subclasses_of(*superclasses))
|
||||
end
|
||||
|
||||
# Exclude this class unless it's a subclass of our supers and is defined.
|
||||
# We check defined? in case we find a removed class that has yet to be
|
||||
# garbage collected. This also fails for anonymous classes -- please
|
||||
# submit a patch if you have a workaround.
|
||||
def subclasses_of(*superclasses) #:nodoc:
|
||||
subclasses = []
|
||||
|
||||
# Exclude this class unless it's a subclass of our supers and is defined.
|
||||
# We check defined? in case we find a removed class that has yet to be
|
||||
# garbage collected. This also fails for anonymous classes -- please
|
||||
# submit a patch if you have a workaround.
|
||||
ObjectSpace.each_object(Class) do |k|
|
||||
if superclasses.any? { |superclass| k < superclass } &&
|
||||
(k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
||||
subclasses << k
|
||||
superclasses.each do |sup|
|
||||
ObjectSpace.each_object(class << sup; self; end) do |k|
|
||||
if k != sup && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
||||
subclasses << k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module String #:nodoc:
|
||||
unless '1.9'.respond_to?(:force_encoding)
|
||||
# Define methods for handling unicode data.
|
||||
module Unicode
|
||||
def self.append_features(base)
|
||||
if '1.8.7'.respond_to?(:chars)
|
||||
base.class_eval { remove_method :chars }
|
||||
end
|
||||
super
|
||||
# Define methods for handling unicode data.
|
||||
module Unicode
|
||||
def self.append_features(base)
|
||||
if '1.8.7 and later'.respond_to?(:chars)
|
||||
base.class_eval { remove_method :chars }
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
unless '1.9'.respond_to?(:force_encoding)
|
||||
# +chars+ is a Unicode safe proxy for string methods. It creates and returns an instance of the
|
||||
# ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all
|
||||
# the String methods are defined on this proxy class. Undefined methods are forwarded to String, so all of the
|
||||
@@ -44,14 +44,12 @@ module ActiveSupport #:nodoc:
|
||||
def is_utf8?
|
||||
ActiveSupport::Multibyte::Handlers::UTF8Handler.consumes?(self)
|
||||
end
|
||||
end
|
||||
else
|
||||
module Unicode #:nodoc:
|
||||
def chars
|
||||
else
|
||||
def chars #:nodoc:
|
||||
self
|
||||
end
|
||||
|
||||
def is_utf8?
|
||||
def is_utf8? #:nodoc:
|
||||
case encoding
|
||||
when Encoding::UTF_8
|
||||
valid_encoding?
|
||||
|
||||
@@ -10,10 +10,12 @@ module ActiveSupport
|
||||
# If you discover an incorrect inflection and require it for your application, you'll need
|
||||
# to correct it yourself (explained below).
|
||||
module Inflector
|
||||
extend self
|
||||
|
||||
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
|
||||
# inflection rules. Examples:
|
||||
#
|
||||
# Inflector.inflections do |inflect|
|
||||
# ActiveSupport::Inflector.inflections do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1\2en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
#
|
||||
@@ -91,13 +93,11 @@ module ActiveSupport
|
||||
end
|
||||
end
|
||||
|
||||
extend self
|
||||
|
||||
# Yields a singleton instance of Inflector::Inflections so you can specify additional
|
||||
# inflector rules.
|
||||
#
|
||||
# Example:
|
||||
# Inflector.inflections do |inflect|
|
||||
# ActiveSupport::Inflector.inflections do |inflect|
|
||||
# inflect.uncountable "rails"
|
||||
# end
|
||||
def inflections
|
||||
@@ -134,7 +134,7 @@ module ActiveSupport
|
||||
# "posts".singularize # => "post"
|
||||
# "octopi".singularize # => "octopus"
|
||||
# "sheep".singluarize # => "sheep"
|
||||
# "word".singluarize # => "word"
|
||||
# "word".singularize # => "word"
|
||||
# "the blue mailmen".singularize # => "the blue mailman"
|
||||
# "CamelOctopi".singularize # => "CamelOctopus"
|
||||
def singularize(word)
|
||||
@@ -307,4 +307,4 @@ module ActiveSupport
|
||||
end
|
||||
end
|
||||
|
||||
require File.dirname(__FILE__) + '/inflections'
|
||||
require 'active_support/inflections'
|
||||
|
||||
@@ -12,6 +12,7 @@ module ActiveSupport
|
||||
else
|
||||
self << [key, value]
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
def [](key)
|
||||
|
||||
@@ -10,19 +10,43 @@ module ActiveSupport
|
||||
end
|
||||
|
||||
def self.included(base)
|
||||
base.send :include, ActiveSupport::Callbacks
|
||||
base.define_callbacks :setup, :teardown
|
||||
base.class_eval do
|
||||
include ActiveSupport::Callbacks
|
||||
define_callbacks :setup, :teardown
|
||||
|
||||
begin
|
||||
require 'mocha'
|
||||
base.alias_method_chain :run, :callbacks_and_mocha
|
||||
rescue LoadError
|
||||
base.alias_method_chain :run, :callbacks
|
||||
if defined?(::Mini)
|
||||
alias_method :run, :run_with_callbacks_and_miniunit
|
||||
else
|
||||
begin
|
||||
require 'mocha'
|
||||
alias_method :run, :run_with_callbacks_and_mocha
|
||||
rescue LoadError
|
||||
alias_method :run, :run_with_callbacks_and_testunit
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_with_callbacks_and_miniunit(runner)
|
||||
result = '.'
|
||||
begin
|
||||
run_callbacks :setup
|
||||
result = super
|
||||
rescue Exception => e
|
||||
result = runner.puke(self.class, self.name, e)
|
||||
ensure
|
||||
begin
|
||||
teardown
|
||||
run_callbacks :teardown, :enumerator => :reverse_each
|
||||
rescue Exception => e
|
||||
result = runner.puke(self.class, self.name, e)
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# This redefinition is unfortunate but test/unit shows us no alternative.
|
||||
def run_with_callbacks(result) #:nodoc:
|
||||
def run_with_callbacks_and_testunit(result) #:nodoc:
|
||||
return if @method_name.to_s == "default_test"
|
||||
|
||||
yield(Test::Unit::TestCase::STARTED, name)
|
||||
|
||||
@@ -38,9 +38,9 @@ class ClassTest < Test::Unit::TestCase
|
||||
@parent = eval("class D; end; D")
|
||||
@sub = eval("class E < D; end; E")
|
||||
@subofsub = eval("class F < E; end; F")
|
||||
assert @parent.subclasses.all? { |i| [@sub.to_s, @subofsub.to_s].include?(i) }
|
||||
assert_equal 2, @parent.subclasses.size
|
||||
assert_equal [@subofsub.to_s], @sub.subclasses
|
||||
assert_equal [], @subofsub.subclasses
|
||||
assert_equal [@sub.to_s, @subofsub.to_s].sort, @parent.subclasses.sort
|
||||
end
|
||||
end
|
||||
|
||||
19
activesupport/test/core_ext/module/model_naming_test.rb
Normal file
19
activesupport/test/core_ext/module/model_naming_test.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
class ModelNamingTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@name = ActiveSupport::ModelName.new('Post::TrackBack')
|
||||
end
|
||||
|
||||
def test_singular
|
||||
assert_equal 'post_track_back', @name.singular
|
||||
end
|
||||
|
||||
def test_plural
|
||||
assert_equal 'post_track_backs', @name.plural
|
||||
end
|
||||
|
||||
def test_partial_path
|
||||
assert_equal 'post/track_backs/track_back', @name.partial_path
|
||||
end
|
||||
end
|
||||
@@ -336,24 +336,26 @@ class TimeWithZoneTest < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_method_missing_with_non_time_return_value
|
||||
silence_warnings do # silence warnings raised by tzinfo gem
|
||||
@twz.time.expects(:foo).returns('bar')
|
||||
assert_equal 'bar', @twz.foo
|
||||
uses_mocha 'TestDatePartValueMethods' do
|
||||
def test_method_missing_with_non_time_return_value
|
||||
silence_warnings do # silence warnings raised by tzinfo gem
|
||||
@twz.time.expects(:foo).returns('bar')
|
||||
assert_equal 'bar', @twz.foo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_date_part_value_methods
|
||||
silence_warnings do # silence warnings raised by tzinfo gem
|
||||
twz = ActiveSupport::TimeWithZone.new(Time.utc(1999,12,31,19,18,17,500), @time_zone)
|
||||
twz.stubs(:method_missing).returns(nil) #ensure these methods are defined directly on class
|
||||
assert_equal 1999, twz.year
|
||||
assert_equal 12, twz.month
|
||||
assert_equal 31, twz.day
|
||||
assert_equal 14, twz.hour
|
||||
assert_equal 18, twz.min
|
||||
assert_equal 17, twz.sec
|
||||
assert_equal 500, twz.usec
|
||||
def test_date_part_value_methods
|
||||
silence_warnings do # silence warnings raised by tzinfo gem
|
||||
twz = ActiveSupport::TimeWithZone.new(Time.utc(1999,12,31,19,18,17,500), @time_zone)
|
||||
twz.stubs(:method_missing).returns(nil) #ensure these methods are defined directly on class
|
||||
assert_equal 1999, twz.year
|
||||
assert_equal 12, twz.month
|
||||
assert_equal 31, twz.day
|
||||
assert_equal 14, twz.hour
|
||||
assert_equal 18, twz.min
|
||||
assert_equal 17, twz.sec
|
||||
assert_equal 500, twz.usec
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -84,6 +84,12 @@ class SetupAndTeardownTest < Test::Unit::TestCase
|
||||
assert_equal [:foo, :sentinel, :foo], self.class.teardown_callback_chain.map(&:method)
|
||||
end
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
def teardown
|
||||
end
|
||||
|
||||
protected
|
||||
def reset_callback_record
|
||||
@called_back = []
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Add new inflection rules using the following format
|
||||
# (all these examples are active by default):
|
||||
# Inflector.inflections do |inflect|
|
||||
# ActiveSupport::Inflector.inflections do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
# inflect.irregular 'person', 'people'
|
||||
|
||||
@@ -98,27 +98,26 @@ module Rails
|
||||
self.name == other.name && self.requirement == other.requirement
|
||||
end
|
||||
|
||||
private ###################################################################
|
||||
|
||||
def specification
|
||||
@spec ||= Gem.source_index.search(Gem::Dependency.new(@name, @requirement)).sort_by { |s| s.version }.last
|
||||
end
|
||||
|
||||
def gem_command
|
||||
RUBY_PLATFORM =~ /win32/ ? 'gem.bat' : 'gem'
|
||||
end
|
||||
private
|
||||
def gem_command
|
||||
RUBY_PLATFORM =~ /win32/ ? 'gem.bat' : 'gem'
|
||||
end
|
||||
|
||||
def install_command
|
||||
cmd = %w(install) << @name
|
||||
cmd << "--version" << %("#{@requirement.to_s}") if @requirement
|
||||
cmd << "--source" << @source if @source
|
||||
cmd
|
||||
end
|
||||
def install_command
|
||||
cmd = %w(install) << @name
|
||||
cmd << "--version" << %("#{@requirement.to_s}") if @requirement
|
||||
cmd << "--source" << @source if @source
|
||||
cmd
|
||||
end
|
||||
|
||||
def unpack_command
|
||||
cmd = %w(unpack) << @name
|
||||
cmd << "--version" << %("#{@requirement.to_s}") if @requirement
|
||||
cmd
|
||||
end
|
||||
def unpack_command
|
||||
cmd = %w(unpack) << @name
|
||||
cmd << "--version" << %("#{@requirement.to_s}") if @requirement
|
||||
cmd
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -74,10 +74,18 @@ module Rails
|
||||
File.join(directory, 'lib')
|
||||
end
|
||||
|
||||
def init_path
|
||||
def classic_init_path
|
||||
File.join(directory, 'init.rb')
|
||||
end
|
||||
|
||||
def gem_init_path
|
||||
File.join(directory, 'rails', 'init.rb')
|
||||
end
|
||||
|
||||
def init_path
|
||||
File.file?(gem_init_path) ? gem_init_path : classic_init_path
|
||||
end
|
||||
|
||||
def has_lib_directory?
|
||||
File.directory?(lib_path)
|
||||
end
|
||||
|
||||
@@ -43,8 +43,6 @@ end
|
||||
# can change this behavior by setting ActionController::Base.allow_concurrency
|
||||
# to true.
|
||||
class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
|
||||
REQUEST_MUTEX = Mutex.new
|
||||
|
||||
# Start the WEBrick server with the given options, mounting the
|
||||
# DispatchServlet at <tt>/</tt>.
|
||||
def self.dispatch(options = {})
|
||||
@@ -73,15 +71,8 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
|
||||
|
||||
def service(req, res) #:nodoc:
|
||||
unless handle_file(req, res)
|
||||
begin
|
||||
REQUEST_MUTEX.lock unless ActionController::Base.allow_concurrency
|
||||
unless handle_dispatch(req, res)
|
||||
raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
|
||||
end
|
||||
ensure
|
||||
unless ActionController::Base.allow_concurrency
|
||||
REQUEST_MUTEX.unlock if REQUEST_MUTEX.locked?
|
||||
end
|
||||
unless handle_dispatch(req, res)
|
||||
raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
1
railties/test/fixtures/plugins/default/gemlike/init.rb
vendored
Normal file
1
railties/test/fixtures/plugins/default/gemlike/init.rb
vendored
Normal file
@@ -0,0 +1 @@
|
||||
raise 'This init.rb should not be evaluated because rails/init.rb exists'
|
||||
2
railties/test/fixtures/plugins/default/gemlike/lib/gemlike.rb
vendored
Normal file
2
railties/test/fixtures/plugins/default/gemlike/lib/gemlike.rb
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
module Gemlike
|
||||
end
|
||||
7
railties/test/fixtures/plugins/default/gemlike/rails/init.rb
vendored
Normal file
7
railties/test/fixtures/plugins/default/gemlike/rails/init.rb
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# I have access to my directory and the Rails config.
|
||||
raise 'directory expected but undefined in init.rb' unless defined? directory
|
||||
raise 'config expected but undefined in init.rb' unless defined? config
|
||||
|
||||
# My lib/ dir must be in the load path.
|
||||
require 'gemlike'
|
||||
raise 'missing mixin from my lib/ dir' unless defined? Gemlike
|
||||
@@ -30,66 +30,66 @@ class Initializer_load_environment_Test < Test::Unit::TestCase
|
||||
|
||||
end
|
||||
|
||||
class Initializer_after_initialize_with_blocks_environment_Test < Test::Unit::TestCase
|
||||
def setup
|
||||
config = ConfigurationMock.new("")
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block1 = "success"
|
||||
uses_mocha 'Initializer after_initialize' do
|
||||
class Initializer_after_initialize_with_blocks_environment_Test < Test::Unit::TestCase
|
||||
def setup
|
||||
config = ConfigurationMock.new("")
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block1 = "success"
|
||||
end
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block2 = "congratulations"
|
||||
end
|
||||
assert_nil $test_after_initialize_block1
|
||||
assert_nil $test_after_initialize_block2
|
||||
|
||||
Rails::Initializer.any_instance.expects(:gems_dependencies_loaded).returns(true)
|
||||
Rails::Initializer.run(:after_initialize, config)
|
||||
end
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block2 = "congratulations"
|
||||
|
||||
def teardown
|
||||
$test_after_initialize_block1 = nil
|
||||
$test_after_initialize_block2 = nil
|
||||
end
|
||||
assert_nil $test_after_initialize_block1
|
||||
assert_nil $test_after_initialize_block2
|
||||
|
||||
Rails::Initializer.any_instance.expects(:gems_dependencies_loaded).returns(true)
|
||||
Rails::Initializer.run(:after_initialize, config)
|
||||
end
|
||||
|
||||
def teardown
|
||||
$test_after_initialize_block1 = nil
|
||||
$test_after_initialize_block2 = nil
|
||||
end
|
||||
|
||||
def test_should_have_called_the_first_after_initialize_block
|
||||
assert_equal "success", $test_after_initialize_block1
|
||||
end
|
||||
|
||||
def test_should_have_called_the_second_after_initialize_block
|
||||
assert_equal "congratulations", $test_after_initialize_block2
|
||||
end
|
||||
end
|
||||
|
||||
class Initializer_after_initialize_with_no_block_environment_Test < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
config = ConfigurationMock.new("")
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block1 = "success"
|
||||
def test_should_have_called_the_first_after_initialize_block
|
||||
assert_equal "success", $test_after_initialize_block1
|
||||
end
|
||||
config.after_initialize # don't pass a block, this is what we're testing!
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block2 = "congratulations"
|
||||
|
||||
def test_should_have_called_the_second_after_initialize_block
|
||||
assert_equal "congratulations", $test_after_initialize_block2
|
||||
end
|
||||
assert_nil $test_after_initialize_block1
|
||||
|
||||
Rails::Initializer.any_instance.expects(:gems_dependencies_loaded).returns(true)
|
||||
Rails::Initializer.run(:after_initialize, config)
|
||||
end
|
||||
|
||||
def teardown
|
||||
$test_after_initialize_block1 = nil
|
||||
$test_after_initialize_block2 = nil
|
||||
end
|
||||
class Initializer_after_initialize_with_no_block_environment_Test < Test::Unit::TestCase
|
||||
def setup
|
||||
config = ConfigurationMock.new("")
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block1 = "success"
|
||||
end
|
||||
config.after_initialize # don't pass a block, this is what we're testing!
|
||||
config.after_initialize do
|
||||
$test_after_initialize_block2 = "congratulations"
|
||||
end
|
||||
assert_nil $test_after_initialize_block1
|
||||
|
||||
def test_should_have_called_the_first_after_initialize_block
|
||||
assert_equal "success", $test_after_initialize_block1, "should still get set"
|
||||
end
|
||||
Rails::Initializer.any_instance.expects(:gems_dependencies_loaded).returns(true)
|
||||
Rails::Initializer.run(:after_initialize, config)
|
||||
end
|
||||
|
||||
def test_should_have_called_the_second_after_initialize_block
|
||||
assert_equal "congratulations", $test_after_initialize_block2
|
||||
end
|
||||
def teardown
|
||||
$test_after_initialize_block1 = nil
|
||||
$test_after_initialize_block2 = nil
|
||||
end
|
||||
|
||||
def test_should_have_called_the_first_after_initialize_block
|
||||
assert_equal "success", $test_after_initialize_block1, "should still get set"
|
||||
end
|
||||
|
||||
def test_should_have_called_the_second_after_initialize_block
|
||||
assert_equal "congratulations", $test_after_initialize_block2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
uses_mocha 'framework paths' do
|
||||
@@ -173,7 +173,7 @@ uses_mocha "Initializer plugin loading tests" do
|
||||
def test_all_plugins_are_loaded_when_registered_plugin_list_is_untouched
|
||||
failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
|
||||
load_plugins!
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :plugin_with_no_lib_dir, :stubby], @initializer.loaded_plugins, failure_tip
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :gemlike, :plugin_with_no_lib_dir, :stubby], @initializer.loaded_plugins, failure_tip
|
||||
end
|
||||
|
||||
def test_all_plugins_loaded_when_all_is_used
|
||||
@@ -181,7 +181,7 @@ uses_mocha "Initializer plugin loading tests" do
|
||||
only_load_the_following_plugins! plugin_names
|
||||
load_plugins!
|
||||
failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
|
||||
assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :plugin_with_no_lib_dir], @initializer.loaded_plugins, failure_tip
|
||||
assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :gemlike, :plugin_with_no_lib_dir], @initializer.loaded_plugins, failure_tip
|
||||
end
|
||||
|
||||
def test_all_plugins_loaded_after_all
|
||||
@@ -189,7 +189,7 @@ uses_mocha "Initializer plugin loading tests" do
|
||||
only_load_the_following_plugins! plugin_names
|
||||
load_plugins!
|
||||
failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
|
||||
assert_plugins [:stubby, :a, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], @initializer.loaded_plugins, failure_tip
|
||||
assert_plugins [:stubby, :a, :gemlike, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], @initializer.loaded_plugins, failure_tip
|
||||
end
|
||||
|
||||
def test_plugin_names_may_be_strings
|
||||
|
||||
@@ -48,16 +48,16 @@ uses_mocha "Plugin Loader Tests" do
|
||||
end
|
||||
|
||||
def test_should_find_all_availble_plugins_and_return_as_all_plugins
|
||||
assert_plugins [:stubby, :plugin_with_no_lib_dir, :acts_as_chunky_bacon, :a], @loader.all_plugins.reverse, @failure_tip
|
||||
assert_plugins [:stubby, :plugin_with_no_lib_dir, :gemlike, :acts_as_chunky_bacon, :a], @loader.all_plugins.reverse, @failure_tip
|
||||
end
|
||||
|
||||
def test_should_return_all_plugins_as_plugins_when_registered_plugin_list_is_untouched
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
|
||||
end
|
||||
|
||||
def test_should_return_all_plugins_as_plugins_when_registered_plugin_list_is_nil
|
||||
@configuration.plugins = nil
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
|
||||
end
|
||||
|
||||
def test_should_return_specific_plugins_named_in_config_plugins_array_if_set
|
||||
@@ -74,17 +74,17 @@ uses_mocha "Plugin Loader Tests" do
|
||||
|
||||
def test_should_load_all_plugins_in_natural_order_when_all_is_used
|
||||
only_load_the_following_plugins! [:all]
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
|
||||
assert_plugins [:a, :acts_as_chunky_bacon, :gemlike, :plugin_with_no_lib_dir, :stubby], @loader.plugins, @failure_tip
|
||||
end
|
||||
|
||||
def test_should_load_specified_plugins_in_order_and_then_all_remaining_plugins_when_all_is_used
|
||||
only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon, :all]
|
||||
assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :plugin_with_no_lib_dir], @loader.plugins, @failure_tip
|
||||
assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :gemlike, :plugin_with_no_lib_dir], @loader.plugins, @failure_tip
|
||||
end
|
||||
|
||||
def test_should_be_able_to_specify_loading_of_plugins_loaded_after_all
|
||||
only_load_the_following_plugins! [:stubby, :all, :acts_as_chunky_bacon]
|
||||
assert_plugins [:stubby, :a, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], @loader.plugins, @failure_tip
|
||||
assert_plugins [:stubby, :a, :gemlike, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], @loader.plugins, @failure_tip
|
||||
end
|
||||
|
||||
def test_should_accept_plugin_names_given_as_strings
|
||||
|
||||
@@ -47,12 +47,12 @@ uses_mocha "Plugin Locator Tests" do
|
||||
end
|
||||
|
||||
def test_should_return_all_plugins_found_under_the_set_plugin_paths
|
||||
assert_equal ["a", "acts_as_chunky_bacon", "plugin_with_no_lib_dir", "stubby"].sort, @locator.plugins.map(&:name).sort
|
||||
assert_equal ["a", "acts_as_chunky_bacon", "gemlike", "plugin_with_no_lib_dir", "stubby"].sort, @locator.plugins.map(&:name).sort
|
||||
end
|
||||
|
||||
def test_should_find_plugins_only_under_the_plugin_paths_set_in_configuration
|
||||
@configuration.plugin_paths = [File.join(plugin_fixture_root_path, "default")]
|
||||
assert_equal ["acts_as_chunky_bacon", "plugin_with_no_lib_dir", "stubby"].sort, @locator.plugins.map(&:name).sort
|
||||
assert_equal ["acts_as_chunky_bacon", "gemlike", "plugin_with_no_lib_dir", "stubby"].sort, @locator.plugins.map(&:name).sort
|
||||
|
||||
@configuration.plugin_paths = [File.join(plugin_fixture_root_path, "alternate")]
|
||||
assert_equal ["a"], @locator.plugins.map(&:name)
|
||||
|
||||
@@ -5,9 +5,10 @@ uses_mocha "Plugin Tests" do
|
||||
class PluginTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@initializer = Rails::Initializer.new(Rails::Configuration.new)
|
||||
@valid_plugin_path = plugin_fixture_path('default/stubby')
|
||||
@empty_plugin_path = plugin_fixture_path('default/empty')
|
||||
@initializer = Rails::Initializer.new(Rails::Configuration.new)
|
||||
@valid_plugin_path = plugin_fixture_path('default/stubby')
|
||||
@empty_plugin_path = plugin_fixture_path('default/empty')
|
||||
@gemlike_plugin_path = plugin_fixture_path('default/gemlike')
|
||||
end
|
||||
|
||||
def test_should_determine_plugin_name_from_the_directory_of_the_plugin
|
||||
@@ -70,7 +71,14 @@ uses_mocha "Plugin Tests" do
|
||||
plugin.stubs(:evaluate_init_rb)
|
||||
plugin.send(:load, @initializer)
|
||||
end
|
||||
|
||||
|
||||
# This path is fine so nothing is raised
|
||||
assert_nothing_raised do
|
||||
plugin = plugin_for(@gemlike_plugin_path)
|
||||
plugin.stubs(:evaluate_init_rb)
|
||||
plugin.send(:load, @initializer)
|
||||
end
|
||||
|
||||
# This is an empty path so it raises
|
||||
assert_raises(LoadError) do
|
||||
plugin = plugin_for(@empty_plugin_path)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user