Compare commits

..

4 Commits

Author SHA1 Message Date
Charlie Somerville
7d4d006cd6 build attrs manually 2013-09-16 19:29:40 +10:00
Charlie Somerville
1b0cb37cf0 use ActionView::Helpers::AssetTagHelper.rails_asset_id instead of env var 2013-09-16 17:55:25 +10:00
Charlie Somerville
8d8cef48cc use fstrings in code that shows up as hot in allocation profiling 2013-09-16 16:57:44 +10:00
Charlie Somerville
37ed643ac7 use a once regexp here since relative_url_root shouldn't ever change 2013-09-16 16:44:30 +10:00
32 changed files with 365 additions and 209 deletions

View File

@@ -1,6 +0,0 @@
# GitHub Rails
This is GitHub's fork of Rails 2.3.
Please note that this fork is **unsupported**. It is not guaranteed to receive security patches or remain stable. **Use at your own risk.**

View File

@@ -23,6 +23,8 @@ task :default => [ :test ]
Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/*_test.rb'
t.verbose = true
t.warning = false
}

View File

@@ -1,14 +0,0 @@
Gem::Specification.new do |s|
s.name = 'actionmailer'
s.version = '2.3.18'
s.summary = 'Service layer for easy email delivery and testing.'
s.description = 'Makes it trivial to test and deliver emails sent from a single service layer.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.add_dependency 'actionpack', '= 2.3.18'
end

View File

@@ -30,12 +30,16 @@ Rake::TestTask.new(:test_action_pack) do |t|
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
t.test_files = Dir.glob( "test/[cftv]*/**/*_test.rb" ).sort
t.verbose = true
#t.warning = true
end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
t.libs << "test"
t.test_files = Dir.glob("test/activerecord/*_test.rb")
t.verbose = true
end

View File

@@ -1,15 +0,0 @@
Gem::Specification.new do |s|
s.name = 'actionpack'
s.version = '2.3.18'
s.summary = 'Web-flow and rendering framework putting the VC in MVC.'
s.description = 'Eases web-request routing, handling, and response as a half-way front, half-way page controller. Implemented with specific emphasis on enabling easy unit/integration testing that doesn\'t require a browser.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.add_dependency 'activesupport', '= 2.3.18'
s.add_dependency 'rack', '~> 1.4'
end

View File

@@ -1332,7 +1332,10 @@ module ActionController #:nodoc:
if action_methods.include?(action_name)
send(action_name)
default_render unless performed?
elsif defined?(self.method_missing) # returns "method" if method_missing is public or protected, but not if it's private
elsif RUBY_VERSION == "1.9.3" && respond_to?(:method_missing)
method_missing action_name.intern
default_render unless performed?
elsif RUBY_VERSION >= "2.0.0" && respond_to?(:method_missing, true) && !method(:method_missing).private?
method_missing action_name.intern
default_render unless performed?
else

View File

@@ -268,7 +268,7 @@ EOM
# Is this an SSL request?
def ssl?
@env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
@env['HTTPS'f] == 'on'f || @env['HTTP_X_FORWARDED_PROTO'f] == 'https'f
end
# Returns the \host for this request, such as "example.com".

View File

@@ -192,7 +192,14 @@ module ActionController
url_for(#{hash_access_method}(opts)) # url_for(hash_for_users_url(opts))
#
end # end
#Add an alias to support the now deprecated formatted_* URL. # #Add an alias to support the now deprecated formatted_* URL.
def formatted_#{selector}(*args) # def formatted_users_url(*args)
ActiveSupport::Deprecation.warn( # ActiveSupport::Deprecation.warn(
"formatted_#{selector}() has been deprecated. " + # "formatted_users_url() has been deprecated. " +
"Please pass format to the standard " + # "Please pass format to the standard " +
"#{selector} method instead.", caller) # "users_url method instead.", caller)
#{selector}(*args) # users_url(*args)
end # end
protected :#{selector} # protected :users_url
end_eval
helpers << selector

View File

@@ -137,6 +137,10 @@ module ActionView
STYLESHEETS_DIR = "#{ASSETS_DIR}/stylesheets"
JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
class << self
attr_accessor :rails_asset_id
end
# Returns a link tag that browsers and news readers can use to auto-detect
# an RSS or ATOM feed. The +type+ can either be <tt>:rss</tt> (default) or
# <tt>:atom</tt>. Control the link options in url_for format using the
@@ -182,7 +186,7 @@ module ActionView
# javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr.js
# javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js
def javascript_path(source)
compute_public_path(source, 'javascripts', 'js')
compute_public_path(source, 'javascripts'f, 'js'f)
end
alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route
@@ -540,7 +544,7 @@ module ActionView
source = rewrite_asset_path(source)
if has_request && include_host
unless source =~ %r{^#{ActionController::Base.relative_url_root}/}
unless source =~ %r{^#{ActionController::Base.relative_url_root}/}o
source = "#{ActionController::Base.relative_url_root}#{source}"
end
end
@@ -583,11 +587,10 @@ module ActionView
@@asset_timestamps_cache = {}
@@asset_timestamps_cache_guard = Mutex.new
# Use the RAILS_ASSET_ID environment variable or the source's
# modification time as its cache-busting asset id.
# Use modification time as its cache-busting asset id.
def rails_asset_id(source)
if asset_id = ENV["RAILS_ASSET_ID"]
asset_id
if ActionView::Helpers::AssetTagHelper.rails_asset_id
ActionView::Helpers::AssetTagHelper.rails_asset_id
else
if @@cache_asset_timestamps && (asset_id = @@asset_timestamps_cache[source])
asset_id
@@ -618,11 +621,11 @@ module ActionView
end
def javascript_src_tag(source, options)
content_tag("script", "", { "type" => Mime::JS, "src" => path_to_javascript(source) }.merge(options))
content_tag("script"f, ""f, { "type"f => Mime::JS, "src"f => path_to_javascript(source) }.merge(options))
end
def stylesheet_tag(source, options)
tag("link", { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen", "href" => html_escape(path_to_stylesheet(source)) }.merge(options), false, false)
tag("link"f, { "rel"f => "stylesheet"f, "type"f => Mime::CSS, "media"f => "screen"f, "href"f => html_escape(path_to_stylesheet(source)) }.merge(options), false, false)
end
def compute_javascript_paths(*args)

View File

@@ -130,19 +130,20 @@ module ActionView
end
def tag_options(options, escape = true)
attrs = ""
unless options.blank?
attrs = []
options.each_pair do |key, value|
attrs << " "
if BOOLEAN_ATTRIBUTES.include?(key)
attrs << %(#{key}="#{key}") if value
attrs << key << '="'f << key << '"'f if value
elsif !value.nil?
final_value = value.is_a?(Array) ? value.join(" ") : value
final_value = value.is_a?(Array) ? value.join(" "f) : value
final_value = html_escape(final_value) if escape
attrs << %(#{key}="#{final_value}")
attrs << key << '="'f << final_value << '"'f
end
end
" #{attrs.sort * ' '}".html_safe unless attrs.empty?
end
attrs.html_safe
end
end
end

View File

@@ -357,6 +357,24 @@ class UrlWriterTests < ActionController::TestCase
ActionController::Routing::Routes.load!
end
def test_formatted_url_methods_are_deprecated
ActionController::Routing::Routes.draw do |map|
map.resources :posts
end
# We need to create a new class in order to install the new named route.
kls = Class.new { include ActionController::UrlWriter }
controller = kls.new
params = {:id => 1, :format => :xml}
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params))
end
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml))
end
ensure
ActionController::Routing::Routes.load!
end
def test_multiple_includes_maintain_distinct_options
first_class = Class.new { include ActionController::UrlWriter }
second_class = Class.new { include ActionController::UrlWriter }

View File

@@ -43,7 +43,7 @@ class AssetTagHelperTest < ActionView::TestCase
def teardown
ActionController::Base.perform_caching = false
ActionController::Base.asset_host = nil
ENV.delete('RAILS_ASSET_ID')
ActionView::Helpers::AssetTagHelper.rails_asset_id = nil
end
AutoDiscoveryToTag = {
@@ -154,12 +154,12 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_javascript_include_tag_with_blank_asset_id
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
JavascriptIncludeToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
def test_javascript_include_tag_with_given_asset_id
ENV["RAILS_ASSET_ID"] = "1"
ActionView::Helpers::AssetTagHelper.rails_asset_id = "1"
assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
end
@@ -169,13 +169,13 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_register_javascript_include_default
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/slider.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
end
def test_register_javascript_include_default_mixed_defaults
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'lib1', '/elsewhere/blub/lib2'
assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/slider.js" type="text/javascript"></script>\n<script src="/javascripts/lib1.js" type="text/javascript"></script>\n<script src="/elsewhere/blub/lib2.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
@@ -187,7 +187,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_custom_javascript_expansions_and_defaults_puts_application_js_at_the_end
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionView::Helpers::AssetTagHelper::register_javascript_expansion :monkey => ["head", "body", "tail"]
assert_dom_equal %(<script src="/javascripts/first.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/head.js" type="text/javascript"></script>\n<script src="/javascripts/body.js" type="text/javascript"></script>\n<script src="/javascripts/tail.js" type="text/javascript"></script>\n<script src="/javascripts/last.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag('first', :defaults, :monkey, 'last')
end
@@ -206,12 +206,12 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_stylesheet_link_tag
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
StyleLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
def test_stylesheet_link_tag_is_html_safe
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
assert stylesheet_link_tag('dir/file').html_safe?
assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe?
assert stylesheet_tag('dir/file', {}).html_safe?
@@ -242,7 +242,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_image_tag_windows_behaviour
old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1"
old_asset_id, ActionView::Helpers::AssetTagHelper.rails_asset_id = ActionView::Helpers::AssetTagHelper.rails_asset_id, "1"
# This simulates the behaviour of File#exist? on windows when testing a file ending in "."
# If the file "rails.png" exists, windows will return true when asked if "rails.png." exists (notice trailing ".")
# OS X, linux etc will return false in this case.
@@ -250,9 +250,9 @@ class AssetTagHelperTest < ActionView::TestCase
assert_equal '<img alt="Rails" src="/images/rails.png?1" />', image_tag('rails.png')
ensure
if old_asset_id
ENV["RAILS_ASSET_ID"] = old_asset_id
ActionView::Helpers::AssetTagHelper.rails_asset_id = old_asset_id
else
ENV.delete("RAILS_ASSET_ID")
ActionView::Helpers::AssetTagHelper.rails_asset_id = nil
end
end
@@ -274,12 +274,12 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_should_use_preset_asset_id
ENV["RAILS_ASSET_ID"] = "4500"
ActionView::Helpers::AssetTagHelper.rails_asset_id = "4500"
assert_equal %(<img alt="Rails" src="/images/rails.png?4500" />), image_tag("rails.png")
end
def test_preset_empty_asset_id
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
assert_equal %(<img alt="Rails" src="/images/rails.png" />), image_tag("rails.png")
end
@@ -291,7 +291,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_image_path_with_caching_and_proc_asset_host_using_request
ENV['RAILS_ASSET_ID'] = ''
ActionView::Helpers::AssetTagHelper.rails_asset_id = ''
ActionController::Base.asset_host = Proc.new do |source, request|
if request.ssl?
"#{request.protocol}#{request.host_with_port}"
@@ -311,7 +311,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_when_caching_on
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
@@ -343,7 +343,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host
ENV['RAILS_ASSET_ID'] = ''
ActionView::Helpers::AssetTagHelper.rails_asset_id = ''
ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" }
ActionController::Base.perform_caching = true
@@ -360,7 +360,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_when_caching_on_with_2_argument_proc_asset_host
ENV['RAILS_ASSET_ID'] = ''
ActionView::Helpers::AssetTagHelper.rails_asset_id = ''
ActionController::Base.asset_host = Proc.new { |source, request|
if request.ssl?
"#{request.protocol}#{request.host_with_port}"
@@ -397,7 +397,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_when_caching_on_with_2_argument_object_asset_host
ENV['RAILS_ASSET_ID'] = ''
ActionView::Helpers::AssetTagHelper.rails_asset_id = ''
ActionController::Base.asset_host = Class.new do
def call(source, request)
if request.ssl?
@@ -437,7 +437,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.asset_host = 'http://a%d.example.com'
ActionController::Base.perform_caching = true
@@ -453,7 +453,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_with_all_and_recursive_puts_defaults_at_the_start_of_the_file
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
@@ -474,7 +474,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_with_all_puts_defaults_at_the_start_of_the_file
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
@@ -495,7 +495,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_with_relative_url_root
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.relative_url_root = "/collaboration/hieraki"
ActionController::Base.perform_caching = true
@@ -520,7 +520,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_javascript_include_tag_when_caching_off
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.perform_caching = false
assert_dom_equal(
@@ -549,7 +549,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_stylesheet_link_tag_when_caching_on
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
@@ -581,7 +581,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_concat_stylesheet_link_tag_when_caching_off
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
assert_dom_equal(
%(<link href="/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" />),
@@ -611,7 +611,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" }
ActionController::Base.perform_caching = true
@@ -628,7 +628,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_stylesheet_link_tag_with_relative_url_root
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.relative_url_root = "/collaboration/hieraki"
ActionController::Base.perform_caching = true
@@ -653,7 +653,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_caching_stylesheet_include_tag_when_caching_off
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper.rails_asset_id = ""
ActionController::Base.perform_caching = false
assert_dom_equal(

View File

@@ -64,6 +64,7 @@ for adapter in %w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase op
end
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
t.test_files=Dir.glob( "test/cases/**/*_test{,_#{adapter_short}}.rb" ).sort
t.verbose = true
}
namespace adapter do

View File

@@ -1,17 +0,0 @@
Gem::Specification.new do |s|
s.name = 'activerecord'
s.version = '2.3.18'
s.summary = 'Implements the ActiveRecord pattern for ORM.'
s.description = 'Implements the ActiveRecord pattern (Fowler, PoEAA) for ORM. It ties database tables and classes together for business objects, like Customer or Subscription, that can find, save, and destroy themselves without resorting to manual SQL.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['README']
s.rdoc_options = ['--main', 'README']
s.extra_rdoc_files = ['README']
s.add_dependency 'activesupport', '= 2.3.18'
end

View File

@@ -2920,23 +2920,15 @@ module ActiveRecord #:nodoc:
attributes.each do |k, v|
if k.to_s.include?("(")
multiparameter_attributes << [ k, v ]
elsif RUBY_VERSION == "1.9.3"
respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
else
_assign_attribute(k, v)
(respond_to?(:"#{k}=", true) && !method(:"#{k}=").private?) ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
end
end
assign_multiparameter_attributes(multiparameter_attributes) unless multiparameter_attributes.empty?
end
def _assign_attribute(k, v)
public_send("#{k}=", v)
rescue NoMethodError => e
if respond_to?("#{k}=")
raise e
else
raise UnknownAttributeError, "unknown attribute: #{k}"
end
end
def create_or_update
raise ReadOnlyRecord if readonly?

View File

@@ -261,7 +261,7 @@ module ActiveRecord
key_records = key_records.inject({}) { |hsh, r| hsh.merge(r.id => r) }
end
calculated_data.inject({}) do |all, row|
calculated_data.inject(ActiveSupport::OrderedHash.new) do |all, row|
key = group_aliases.map{|group_alias| type_cast_calculated_value(row[group_alias], group_columns[group_alias])}
key = key.first if key.size == 1
key = key_records[key] if associated

View File

@@ -295,7 +295,7 @@ module ActiveRecord
# Removes all errors that have been added.
def clear
@errors = {}
@errors = ActiveSupport::OrderedHash.new
end
# Returns the total number of errors added. Two errors added to the same attribute will be counted as such.

View File

@@ -552,7 +552,7 @@ module NestedAttributesOnACollectionAssociationTests
end
def test_should_sort_the_hash_by_the_keys_before_building_new_associated_models
attributes = {}
attributes = ActiveSupport::OrderedHash.new
attributes['123726353'] = { :name => 'Grace OMalley' }
attributes['2'] = { :name => 'Privateers Greed' } # 2 is lower then 123726353
@pirate.send(association_setter, attributes)
@@ -562,6 +562,7 @@ module NestedAttributesOnACollectionAssociationTests
def test_should_raise_an_argument_error_if_something_else_than_a_hash_is_passed
assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, {}) }
assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, ActiveSupport::OrderedHash.new) }
assert_raise_with_message ArgumentError, 'Hash or Array expected, got String ("foo")' do
@pirate.send(association_setter, "foo")

View File

@@ -31,6 +31,8 @@ Rake::TestTask.new { |t|
t.libs << activesupport_path if File.directory?(activesupport_path)
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.warning = true
}

View File

@@ -1,17 +0,0 @@
Gem::Specification.new do |s|
s.name = 'activeresource'
s.version = '2.3.18'
s.summary = 'Think Active Record for web resources.'
s.description = 'Wraps web resources in model classes that can be manipulated through XML over REST.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['README']
s.rdoc_options = ['--main', 'README']
s.extra_rdoc_files = ['README']
s.add_dependency 'activesupport', '= 2.3.18'
end

View File

@@ -18,6 +18,8 @@ task :default => :test
Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.warning = true
}
# Create compressed packages

View File

@@ -1,12 +0,0 @@
Gem::Specification.new do |s|
s.name = 'activesupport'
s.version = '2.3.18'
s.summary = 'Support and utility classes used by the Rails framework.'
s.description = 'Utility library which carries commonly used classes and goodies from the Rails framework'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
end

View File

@@ -1,6 +1,40 @@
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'
# Collect an enumerable into sets, grouped by the result of a block. Useful,
# for example, for grouping records by date.
#
# Example:
#
# latest_transcripts.group_by(&:day).each do |day, transcripts|
# p "#{day} -> #{transcripts.map(&:class).join(', ')}"
# end
# "2006-03-01 -> Transcript"
# "2006-02-28 -> Transcript"
# "2006-02-27 -> Transcript, Transcript"
# "2006-02-26 -> Transcript, Transcript"
# "2006-02-25 -> Transcript"
# "2006-02-24 -> Transcript, Transcript"
# "2006-02-23 -> Transcript"
def group_by
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:
#
# payments.sum { |p| p.price * p.tax_rate }
@@ -28,6 +62,26 @@ module Enumerable
end
end
# Iterates over a collection, passing the current element *and* the
# +memo+ to the block. Handy for building up hashes or
# reducing collections down to one object. Examples:
#
# %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'}
#
# *Note* that you can't use immutable objects like numbers, true or false as
# the memo. You would think the following returns 120, but since the memo is
# never changed, it does not.
#
# (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
#
def each_with_object(memo, &block)
memo.tap do |m|
each do |element|
block.call(element, m)
end
end
end unless [].respond_to?(:each_with_object)
# Convert an enumerable to a hash. Examples:
#
# people.index_by(&:login)
@@ -49,6 +103,15 @@ module Enumerable
size > 1
end
# Returns true if none of the elements match the given block.
#
# success = responses.none? {|r| r.status / 100 == 5 }
#
# This is a builtin method in Ruby 1.8.7 and later.
def none?(&block)
!any?(&block)
end unless [].respond_to?(:none?)
# The negative of the Enumerable#include?. Returns true if the collection does not include the object.
def exclude?(object)

View File

@@ -1 +1,168 @@
ActiveSupport::OrderedHash = Hash
require 'yaml'
YAML.add_builtin_type("omap") do |type, val|
ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
end
# OrderedHash is namespaced to prevent conflicts with other implementations
module ActiveSupport
class OrderedHash < ::Hash #:nodoc:
def to_yaml_type
"!tag:yaml.org,2002:omap"
end
def to_yaml(opts = {})
YAML.quick_emit(self, opts) do |out|
out.seq(taguri, to_yaml_style) do |seq|
each do |k, v|
seq.add(k => v)
end
end
end
end
# Hash is ordered in Ruby 1.9!
if RUBY_VERSION < '1.9'
def initialize(*args, &block)
super
@keys = []
end
def self.[](*args)
ordered_hash = new
if (args.length == 1 && args.first.is_a?(Array))
args.first.each do |key_value_pair|
next unless (key_value_pair.is_a?(Array))
ordered_hash[key_value_pair[0]] = key_value_pair[1]
end
return ordered_hash
end
unless (args.size % 2 == 0)
raise ArgumentError.new("odd number of arguments for Hash")
end
args.each_with_index do |val, ind|
next if (ind % 2 != 0)
ordered_hash[val] = args[ind + 1]
end
ordered_hash
end
def initialize_copy(other)
super
# make a deep copy of keys
@keys = other.keys
end
def []=(key, value)
@keys << key if !has_key?(key)
super
end
def delete(key)
if has_key? key
index = @keys.index(key)
@keys.delete_at index
end
super
end
def delete_if
super
sync_keys!
self
end
def reject!
super
sync_keys!
self
end
def reject(&block)
dup.reject!(&block)
end
def keys
@keys.dup
end
def values
@keys.collect { |key| self[key] }
end
def to_hash
self
end
def to_a
@keys.map { |key| [ key, self[key] ] }
end
def each_key
@keys.each { |key| yield key }
end
def each_value
@keys.each { |key| yield self[key]}
end
def each
@keys.each {|key| yield [key, self[key]]}
end
alias_method :each_pair, :each
def clear
super
@keys.clear
self
end
def shift
k = @keys.first
v = delete(k)
[k, v]
end
def merge!(other_hash)
if block_given?
other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
else
other_hash.each { |k, v| self[k] = v }
end
self
end
alias_method :update, :merge!
def merge(other_hash, &block)
dup.merge!(other_hash, &block)
end
# When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
def replace(other)
super
@keys = other.keys
self
end
def invert
OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}]
end
def inspect
"#<OrderedHash #{super}>"
end
private
def sync_keys!
@keys.delete_if {|k| !has_key?(k)}
end
end
end
end

View File

@@ -1,5 +1,5 @@
module ActiveSupport #:nodoc:
class OrderedOptions < Hash #:nodoc:
class OrderedOptions < OrderedHash #:nodoc:
def []=(key, value)
super(key.to_sym, value)
end

View File

@@ -178,8 +178,6 @@ class MemoryStoreTest < ActiveSupport::TestCase
end
uses_memcached 'memcached backed store' do
next # these tests are broken on CI
class MemCacheStoreTest < ActiveSupport::TestCase
def setup
@cache = ActiveSupport::Cache.lookup_store(:mem_cache_store)

View File

@@ -35,6 +35,8 @@ end
Rake::TestTask.new("regular_test") do |t|
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.warning = true
t.verbose = true
end

View File

@@ -20,7 +20,7 @@ module RailsGuides
def process(string, current_level=3, counters=[1])
s = StringScanner.new(string)
level_hash = {}
level_hash = ActiveSupport::OrderedHash.new
while !s.eos?
re = %r{^h(\d)(?:\((#.*?)\))?\s*\.\s*(.*)$}

View File

@@ -34,7 +34,7 @@ module Rails
def initialize(app)
@app = app
@metals = {}
@metals = ActiveSupport::OrderedHash.new
self.class.metals.each { |app| @metals[app] = true }
freeze
end

View File

@@ -1,22 +0,0 @@
Gem::Specification.new do |s|
s.name = 'rails'
s.version = '2.3.18'
s.summary = 'Web-application framework with template engine, control-flow layer, and ORM.'
s.description = "Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick\non top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates."
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['bin/rails']
s.executables = ['rails']
s.rdoc_options = ['--exclude', '.']
s.add_dependency 'rake', '>= 0.8.3'
s.add_dependency 'activesupport', '= 2.3.18'
s.add_dependency 'activerecord', '= 2.3.18'
s.add_dependency 'actionpack', '= 2.3.18'
s.add_dependency 'actionmailer', '= 2.3.18'
s.add_dependency 'activeresource', '= 2.3.18'
end

View File

@@ -3,5 +3,38 @@
set -x
set -e
script/cibuild-on 1.9.3-p231-tcs-github
script/cibuild-on 2.0.0-github
RUBY_VERSION="$(cat .ruby-version)"
# Use the right Ruby /without/ rbenv
ruby_dir=$(dirname "$(RBENV_VERSION=$RUBY_VERSION rbenv which ruby)")
export PATH=$ruby_dir:$PATH
# Announce who we are
ruby -v
# Because Rails 2.3 doesn't use Bundler for its own tests,
# we need to setup an isolated gem environment.
gem_environment_version="$(md5sum Gemfile.sh | cut -d' ' -f1)-$(ruby -e 'print RUBY_VERSION')"
gem_dir=`pwd`/.gem
gem_pristine_dir=${gem_dir}-${gem_environment_version}
export GEM_HOME=$gem_dir
export GEM_PATH=$gem_dir:$GEM_PATH
export GEM_ROOT=$gem_dir
rm -rf $gem_dir
if [ ! -d $gem_pristine_dir ]; then
mkdir $gem_dir
. Gemfile.sh
mv $gem_dir $gem_pristine_dir
fi
cp -r $gem_pristine_dir $gem_dir
# Go ham
rake

View File

@@ -1,40 +0,0 @@
#!/bin/bash
set -x
set -e
RUBY_VERSION="$1"
# Use the right Ruby /without/ rbenv
ruby_dir=$(dirname "$(RBENV_VERSION=$RUBY_VERSION rbenv which ruby)")
export PATH=$ruby_dir:$PATH
# Announce who we are
ruby -v
# Because Rails 2.3 doesn't use Bundler for its own tests,
# we need to setup an isolated gem environment.
gem_environment_version="$(md5sum Gemfile.sh | cut -d' ' -f1)-$(ruby -e 'print RUBY_VERSION')"
gem_dir=`pwd`/.gem
gem_pristine_dir=${gem_dir}-${gem_environment_version}
export GEM_HOME=$gem_dir
export GEM_PATH=$gem_dir:$GEM_PATH
export GEM_ROOT=$gem_dir
rm -rf $gem_dir
if [ ! -d $gem_pristine_dir ]; then
mkdir $gem_dir
. Gemfile.sh
mv $gem_dir $gem_pristine_dir
fi
cp -r $gem_pristine_dir $gem_dir
# Go ham
rake