diff options
author | Xavier Noria <fxn@hashref.com> | 2010-07-30 02:35:24 +0200 |
---|---|---|
committer | Xavier Noria <fxn@hashref.com> | 2010-07-30 02:35:24 +0200 |
commit | ccd45618ed9a629c9535a5ff84ef5c238befa4ab (patch) | |
tree | 0a582bf695dce01240762d2b8516efde43bc3515 | |
parent | 3c3ff1377d17b584dd14d85c7cecab59ddff2679 (diff) | |
parent | 755af497555fde16db86f7e51f6462b0aca79b49 (diff) | |
download | rails-ccd45618ed9a629c9535a5ff84ef5c238befa4ab.tar.gz rails-ccd45618ed9a629c9535a5ff84ef5c238befa4ab.tar.bz2 rails-ccd45618ed9a629c9535a5ff84ef5c238befa4ab.zip |
Merge remote branch 'rails/master'
71 files changed, 303 insertions, 172 deletions
@@ -39,7 +39,6 @@ platforms :ruby do end platforms :jruby do - gem "system_timer" gem "ruby-debug", ">= 0.10.3" gem "activerecord-jdbcsqlite3-adapter" diff --git a/RAILS_VERSION b/RAILS_VERSION index c3eddb1401..7706a9b5ac 100644 --- a/RAILS_VERSION +++ b/RAILS_VERSION @@ -1 +1 @@ -3.0.0.beta4 +3.0.0.rc diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG index f0b9368874..76eab935e5 100644 --- a/actionmailer/CHANGELOG +++ b/actionmailer/CHANGELOG @@ -1,3 +1,8 @@ +*Rails 3.0.0 [release candidate] (July 26th, 2010)* + +* No material changes + + *Rails 3.0.0 [beta 4] (June 8th, 2010)* * subject is automatically looked up on I18n using mailer_name and action_name as scope as in t(".subject") [JK] diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 1ac8f9da1d..f742f982f2 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -493,10 +493,10 @@ module ActionMailer #:nodoc: # You can also search for specific attachments: # # # By Filename - # mail.attachments['filename.jpg'] #=> Mail::Part object or nil + # mail.attachments['filename.jpg'] # => Mail::Part object or nil # # # or by index - # mail.attachments[0] #=> Mail::Part (first attachment) + # mail.attachments[0] # => Mail::Part (first attachment) # def attachments @_message.attachments diff --git a/actionmailer/lib/action_mailer/version.rb b/actionmailer/lib/action_mailer/version.rb index 8c19082f61..805c89be1d 100644 --- a/actionmailer/lib/action_mailer/version.rb +++ b/actionmailer/lib/action_mailer/version.rb @@ -3,7 +3,7 @@ module ActionMailer MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 6e07516a58..81abb8b5f1 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,4 +1,4 @@ -*Rails 3.0.0 [Release Candidate] (unreleased)* +*Rails 3.0.0 [release candidate] (July 26th, 2010)* * Allow stylesheet/javascript extensions to be changed through railties. [Josh Kalderimis] @@ -33,6 +33,7 @@ * Removed textilize, textilize_without_paragraph and markdown helpers. [Santiago Pastorino] + *Rails 3.0.0 [beta 4] (June 8th, 2010)* * Remove middleware laziness [José Valim] diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 50d8e91c47..aeec934be8 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -47,6 +47,7 @@ module ActionDispatch end autoload_under 'middleware' do + autoload :BestStandardsSupport autoload :Callbacks autoload :Cookies autoload :Flash diff --git a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb new file mode 100644 index 0000000000..df8f7766bb --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb @@ -0,0 +1,13 @@ +module ActionDispatch + class BestStandardsSupport + def initialize(app) + @app = app + end + + def call(env) + status, headers, body = @app.call(env) + headers["X-UA-Compatible"] = "IE=Edge,chrome=1" + [status, headers, body] + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb index ad98249468..dd82294644 100644 --- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb @@ -191,11 +191,8 @@ module ActionDispatch def load_session(env) stale_session_check! do - if sid = current_session_id(env) - sid, session = get_session(env, sid) - else - sid, session = generate_sid, {} - end + sid = current_session_id(env) + sid, session = get_session(env, sid) [sid, session] end end diff --git a/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb b/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb index 5304440418..28e3dbd732 100644 --- a/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb @@ -25,6 +25,7 @@ module ActionDispatch private def get_session(env, sid) + sid ||= generate_sid begin session = @pool.get(sid) || {} rescue MemCache::MemCacheError, Errno::ECONNREFUSED diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index ed93211255..a3af37947a 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -7,10 +7,11 @@ module ActionDispatch config.action_dispatch.x_sendfile_header = "" config.action_dispatch.ip_spoofing_check = true config.action_dispatch.show_exceptions = true + config.action_dispatch.best_standards_support = true # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| ActionDispatch::Callbacks.to_prepare { app.routes_reloader.execute_if_updated } end end -end
\ No newline at end of file +end diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 9b42f26289..ba93ff8630 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -20,7 +20,7 @@ module ActionDispatch # <%= link_to('Click here', :controller => 'users', # :action => 'new', :message => 'Welcome!') %> # - # #=> Generates a link to: /users/new?message=Welcome%21 + # # Generates a link to /users/new?message=Welcome%21 # # link_to, and all other functions that require URL generation functionality, # actually use ActionController::UrlFor under the hood. And in particular, diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb index 532d060c06..7eaf7d0534 100644 --- a/actionpack/lib/action_pack/version.rb +++ b/actionpack/lib/action_pack/version.rb @@ -3,7 +3,7 @@ module ActionPack MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 1a899c6aee..a8ca19931b 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -90,11 +90,12 @@ class JavaScriptHelperTest < ActionView::TestCase end def test_link_to_function_with_inner_block_does_not_raise_exception - html = link_to_function("Greet me!") do |page| - content_tag(:h1) { 'Hi' } + html = link_to_function( "Greet me!" ) do |page| + page.replace_html 'header', (content_tag :h1 do + 'Greetings' + end) end - - assert_dom_equal %(<a href='#' onclick="; return false;">Greet me!</a>), html + assert_dom_equal %(<a href="#" onclick="Element.update("header", "\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E");; return false;">Greet me!</a>), html end def test_javascript_tag diff --git a/activemodel/CHANGELOG b/activemodel/CHANGELOG index 33602657f5..8374853231 100644 --- a/activemodel/CHANGELOG +++ b/activemodel/CHANGELOG @@ -1,4 +1,4 @@ -*Rails 3.0.0 [Release Candidate] (unreleased)* +*Rails 3.0.0 [release candidate] (July 26th, 2010)* * Added ActiveModel::MassAssignmentSecurity [Eric Chapweske, Josh Kalderimis] diff --git a/activemodel/lib/active_model/conversion.rb b/activemodel/lib/active_model/conversion.rb index 2a1650faa9..d2bd160dc7 100644 --- a/activemodel/lib/active_model/conversion.rb +++ b/activemodel/lib/active_model/conversion.rb @@ -17,9 +17,9 @@ module ActiveModel # end # # cm = ContactMessage.new - # cm.to_model == self #=> true - # cm.to_key #=> nil - # cm.to_param #=> nil + # cm.to_model == self # => true + # cm.to_key # => nil + # cm.to_param # => nil # module Conversion # If your object is already designed to implement all of the Active Model diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 482b3dac47..bf93126d27 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -83,8 +83,8 @@ module ActiveModel # When passed a symbol or a name of a method, returns an array of errors # for the method. # - # p.errors[:name] #=> ["can not be nil"] - # p.errors['name'] #=> ["can not be nil"] + # p.errors[:name] # => ["can not be nil"] + # p.errors['name'] # => ["can not be nil"] def [](attribute) if errors = get(attribute.to_sym) errors @@ -96,7 +96,7 @@ module ActiveModel # Adds to the supplied attribute the supplied error message. # # p.errors[:name] = "must be set" - # p.errors[:name] #=> ['must be set'] + # p.errors[:name] # => ['must be set'] def []=(attribute, error) self[attribute.to_sym] << error end @@ -124,9 +124,9 @@ module ActiveModel # Returns the number of error messages. # # p.errors.add(:name, "can't be blank") - # p.errors.size #=> 1 + # p.errors.size # => 1 # p.errors.add(:name, "must be specified") - # p.errors.size #=> 2 + # p.errors.size # => 2 def size values.flatten.size end @@ -135,16 +135,16 @@ module ActiveModel # # p.errors.add(:name, "can't be blank") # p.errors.add(:name, "must be specified") - # p.errors.to_a #=> ["name can't be blank", "name must be specified"] + # p.errors.to_a # => ["name can't be blank", "name must be specified"] def to_a full_messages end # Returns the number of error messages. # p.errors.add(:name, "can't be blank") - # p.errors.count #=> 1 + # p.errors.count # => 1 # p.errors.add(:name, "must be specified") - # p.errors.count #=> 2 + # p.errors.count # => 2 def count to_a.size end @@ -158,8 +158,8 @@ module ActiveModel # # p.errors.add(:name, "can't be blank") # p.errors.add(:name, "must be specified") - # p.errors.to_xml #=> Produces: - # + # p.errors.to_xml + # # => # # <?xml version=\"1.0\" encoding=\"UTF-8\"?> # # <errors> # # <error>name can't be blank</error> diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index dc83932dde..b74d669f0a 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -17,7 +17,10 @@ module ActiveModel end # Transform the model name into a more humane format, using I18n. By default, - # it will underscore then humanize the class name (BlogPost.model_name.human #=> "Blog post"). + # it will underscore then humanize the class name + # + # BlogPost.model_name.human # => "Blog post" + # # Specify +options+ with additional translating options. def human(options={}) return @human unless @klass.respond_to?(:lookup_ancestors) && @@ -45,8 +48,8 @@ module ActiveModel # extend ActiveModel::Naming # end # - # BookCover.model_name #=> "BookCover" - # BookCover.model_name.human #=> "Book cover" + # BookCover.model_name # => "BookCover" + # BookCover.model_name.human # => "Book cover" # # Providing the functionality that ActiveModel::Naming provides in your object # is required to pass the Active Model Lint test. So either extending the provided diff --git a/activemodel/lib/active_model/translation.rb b/activemodel/lib/active_model/translation.rb index 0554677296..0facbd6ce1 100644 --- a/activemodel/lib/active_model/translation.rb +++ b/activemodel/lib/active_model/translation.rb @@ -14,7 +14,7 @@ module ActiveModel # end # # TranslatedPerson.human_attribute_name('my_attribute') - # #=> "My attribute" + # # => "My attribute" # # This also provides the required class methods for hooking into the # Rails internationalization API, including being able to define a diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 5779ba3b29..1a58d4c4fb 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -24,20 +24,16 @@ module ActiveModel # end # # Which provides you with the full standard validation stack that you - # know from ActiveRecord. + # know from Active Record: # # person = Person.new - # person.valid? - # #=> true - # person.invalid? - # #=> false + # person.valid? # => true + # person.invalid? # => false + # # person.first_name = 'zoolander' - # person.valid? - # #=> false - # person.invalid? - # #=> true - # person.errors - # #=> #<OrderedHash {:first_name=>["starts with z."]}> + # person.valid? # => false + # person.invalid? # => true + # person.errors # => #<OrderedHash {:first_name=>["starts with z."]}> # # Note that ActiveModel::Validations automatically adds an +errors+ method # to your instances initialized with a new ActiveModel::Errors object, so diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb index 689c617177..52192d5988 100644 --- a/activemodel/lib/active_model/validator.rb +++ b/activemodel/lib/active_model/validator.rb @@ -102,8 +102,8 @@ module ActiveModel #:nodoc: # # == Examples # - # PresenceValidator.kind #=> :presence - # UniquenessValidator.kind #=> :uniqueness + # PresenceValidator.kind # => :presence + # UniquenessValidator.kind # => :uniqueness # def self.kind @kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym unless anonymous? diff --git a/activemodel/lib/active_model/version.rb b/activemodel/lib/active_model/version.rb index c36fc8b1f7..f2f4b15520 100644 --- a/activemodel/lib/active_model/version.rb +++ b/activemodel/lib/active_model/version.rb @@ -3,7 +3,7 @@ module ActiveModel MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 679fdafae8..20b2286fc0 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,4 +1,4 @@ -*Rails 3.0.0 [RC1] (unreleased)* +*Rails 3.0.0 [release candidate] (July 26th, 2010)* * Changed update_attribute to not run callbacks and update the record directly in the database [Neeraj Singh] diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 4ce3b34819..b5159eead3 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -422,7 +422,7 @@ module ActiveRecord match = DynamicFinderMatch.match(method) if match && match.creator? attributes = match.attribute_names - return send(:"find_by_#{attributes.join('and')}", *args) || create(Hash[attributes.zip(args)]) + return send(:"find_by_#{attributes.join('_and_')}", *args) || create(Hash[attributes.zip(args)]) end if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 5898ec3732..391c287fe4 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -803,7 +803,7 @@ module ActiveRecord #:nodoc: end def arel_table - @arel_table ||= Arel::Table.new(table_name, :engine => arel_engine) + @arel_table ||= Arel::Table.new(table_name, arel_engine) end def arel_engine diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 69a963c3d3..d8c92d0ad3 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -34,13 +34,11 @@ module ActiveRecord include QueryCache include ActiveSupport::Callbacks - attr_accessor :runtime define_callbacks :checkout, :checkin def initialize(connection, logger = nil) #:nodoc: @active = nil @connection, @logger = connection, logger - @runtime = 0 @query_cache_enabled = false @query_cache = {} @instrumenter = ActiveSupport::Notifications.instrumenter @@ -92,11 +90,6 @@ module ActiveRecord false end - def reset_runtime #:nodoc: - rt, @runtime = @runtime, 0 - rt - end - # QUOTING ================================================== # Override to return the quoted table name. Defaults to column quoting. diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb index f7ae5587ed..c7ae12977a 100644 --- a/activerecord/lib/active_record/log_subscriber.rb +++ b/activerecord/lib/active_record/log_subscriber.rb @@ -1,13 +1,25 @@ module ActiveRecord class LogSubscriber < ActiveSupport::LogSubscriber + def self.runtime=(value) + Thread.current["active_record_sql_runtime"] = value + end + + def self.runtime + Thread.current["active_record_sql_runtime"] ||= 0 + end + + def self.reset_runtime + rt, self.runtime = runtime, 0 + rt + end + def initialize super @odd_or_even = false end def sql(event) - connection = ActiveRecord::Base.connection - connection.runtime += event.duration + self.class.runtime += event.duration return unless logger.debug? name = '%s (%.1fms)' % [event.payload[:name], event.duration] @@ -33,4 +45,4 @@ module ActiveRecord end end -ActiveRecord::LogSubscriber.attach_to :active_record +ActiveRecord::LogSubscriber.attach_to :active_record
\ No newline at end of file diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index cf8c5aaf84..e652296e2c 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -78,7 +78,7 @@ module ActiveRecord # member.avatar_attributes = { :id => '2', :_destroy => '1' } # member.avatar.marked_for_destruction? # => true # member.save - # member.reload.avatar #=> nil + # member.reload.avatar # => nil # # Note that the model will _not_ be destroyed until the parent is saved. # @@ -180,7 +180,7 @@ module ActiveRecord # # member.attributes = params['member'] # member.posts.detect { |p| p.id == 2 }.marked_for_destruction? # => true - # member.posts.length #=> 2 + # member.posts.length # => 2 # member.save # member.reload.posts.length # => 1 # diff --git a/activerecord/lib/active_record/railties/controller_runtime.rb b/activerecord/lib/active_record/railties/controller_runtime.rb index cf74fa1655..bc6ca936c0 100644 --- a/activerecord/lib/active_record/railties/controller_runtime.rb +++ b/activerecord/lib/active_record/railties/controller_runtime.rb @@ -11,10 +11,9 @@ module ActiveRecord def cleanup_view_runtime if ActiveRecord::Base.connected? - connection = ActiveRecord::Base.connection - db_rt_before_render = connection.reset_runtime + db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime runtime = super - db_rt_after_render = connection.reset_runtime + db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime self.db_runtime = db_rt_before_render + db_rt_after_render runtime - db_rt_after_render else diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 86a210d2be..a8cea44c78 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -108,7 +108,7 @@ module ActiveRecord # ==== Example # # Comment.where(:post_id => 1).scoping do - # Comment.first #=> SELECT * FROM comments WHERE post_id = 1 + # Comment.first # SELECT * FROM comments WHERE post_id = 1 # end # # Please check unscoped if you want to remove all previous scopes (including diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 0593897fa5..716e7275a5 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -47,9 +47,9 @@ module ActiveRecord clone.tap {|r| r.joins_values += args if args.present? } end - def where(*args) - value = build_where(*args) - clone.tap {|r| r.where_values += Array.wrap(value) if value.present? } + def where(opts, other = nil) + value = build_where(opts, other) + value ? clone.tap {|r| r.where_values += Array.wrap(value) } : clone end def having(*args) @@ -166,13 +166,10 @@ module ActiveRecord arel end - def build_where(*args) - return if args.blank? - - opts = args.first + def build_where(opts, other = nil) case opts when String, Array - @klass.send(:sanitize_sql, args.size > 1 ? args : opts) + @klass.send(:sanitize_sql, other ? [opts, other] : opts) when Hash attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts) PredicateBuilder.new(table.engine).build_from_hash(attributes, table) diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb index 766e63edc7..becde0fbfd 100644 --- a/activerecord/lib/active_record/session_store.rb +++ b/activerecord/lib/active_record/session_store.rb @@ -293,6 +293,7 @@ module ActiveRecord private def get_session(env, sid) Base.silence do + sid ||= generate_sid session = find_session(sid) env[SESSION_RECORD_KEY] = session [sid, session.data] diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb index d18fed0131..a467ffa960 100644 --- a/activerecord/lib/active_record/version.rb +++ b/activerecord/lib/active_record/version.rb @@ -3,7 +3,7 @@ module ActiveRecord MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 6fe737a817..ac2021c369 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -167,6 +167,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase companies(:first_firm).readonly_clients.find(:all).each { |c| assert c.readonly? } end + def test_dynamic_find_or_create_from_two_attributes_using_an_association + author = authors(:david) + number_of_posts = Post.count + another = author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body") + assert_equal number_of_posts + 1, Post.count + assert_equal another, author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body") + assert !another.new_record? + end + def test_cant_save_has_many_readonly_association authors(:david).readonly_comments.each { |c| assert_raise(ActiveRecord::ReadOnlyRecord) { c.save! } } authors(:david).readonly_comments.each { |c| assert c.readonly? } diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 08694526af..49e7147773 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -13,6 +13,8 @@ require 'models/post' require 'models/reader' require 'models/ship' require 'models/ship_part' +require 'models/tag' +require 'models/tagging' require 'models/treasure' require 'models/company' diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb index 342daa19df..cbaaca764b 100644 --- a/activerecord/test/cases/log_subscriber_test.rb +++ b/activerecord/test/cases/log_subscriber_test.rb @@ -57,4 +57,8 @@ class LogSubscriberTest < ActiveRecord::TestCase wait assert_equal 0, @logger.logged(:debug).size end + + def test_initializes_runtime + Thread.new { assert_equal 0, ActiveRecord::LogSubscriber.runtime }.join + end end diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG index 2b2092b9fe..8fa1b0b4b3 100644 --- a/activeresource/CHANGELOG +++ b/activeresource/CHANGELOG @@ -1,3 +1,8 @@ +*Rails 3.0.0 [release candidate] (July 26th, 2010)* + +* No material changes + + *Rails 3.0.0 [beta 4] (June 8th, 2010)* * JSON: set Base.include_root_in_json = true to include a root value in the JSON: {"post": {"title": ...}}. Mirrors the Active Record option. [Santiago Pastorino] diff --git a/activeresource/lib/active_resource/version.rb b/activeresource/lib/active_resource/version.rb index 198e77a3d1..43c00e9cf1 100644 --- a/activeresource/lib/active_resource/version.rb +++ b/activeresource/lib/active_resource/version.rb @@ -3,7 +3,7 @@ module ActiveResource MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 8706a2aa0b..8485e7d46b 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,4 +1,4 @@ -*Rails 3.0.0 [Release Candidate] (unreleased)* +*Rails 3.0.0 [release candidate] (July 26th, 2010)* * Removed Object#returning, Object#tap should be used instead. [Santiago Pastorino] diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 037cfffae2..8e90de110a 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -19,8 +19,6 @@ module ActiveSupport autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store' autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store' - EMPTY_OPTIONS = {}.freeze - # These options mean something to all cache implementations. Individual cache # implementations may support additional options. UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl] diff --git a/activesupport/lib/active_support/core_ext/array/uniq_by.rb b/activesupport/lib/active_support/core_ext/array/uniq_by.rb index a09b2302fd..bd5c7a187f 100644 --- a/activesupport/lib/active_support/core_ext/array/uniq_by.rb +++ b/activesupport/lib/active_support/core_ext/array/uniq_by.rb @@ -2,7 +2,7 @@ class Array # Return an unique array based on the criteria given as a proc. # # [1, 2, 3, 4].uniq_by { |i| i.odd? } - # #=> [1, 2] + # # => [1, 2] # def uniq_by hash, array = {}, [] diff --git a/activesupport/lib/active_support/core_ext/array/wrap.rb b/activesupport/lib/active_support/core_ext/array/wrap.rb index e211bdeeca..09a1c2e5a1 100644 --- a/activesupport/lib/active_support/core_ext/array/wrap.rb +++ b/activesupport/lib/active_support/core_ext/array/wrap.rb @@ -1,9 +1,14 @@ class Array - # Wraps the object in an Array unless it's an Array. Converts the - # object to an Array using #to_ary if it implements that. + # <tt>Array.wrap</tt> is like <tt>Kernel#Array</tt> except: # - # It differs with Array() in that it does not call +to_a+ on - # the argument: + # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt> + # moves on to try +to_a+ if the returned value is +nil+, but <tt>Arraw.wrap</tt> returns + # such a +nil+ right away. + # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt> + # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value. + # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array. + # + # The last point is particularly worth comparing for some enumerables: # # Array(:foo => :bar) # => [[:foo, :bar]] # Array.wrap(:foo => :bar) # => [{:foo => :bar}] diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index d0821a7c68..f76ed401cd 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -66,7 +66,8 @@ module Enumerable # +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'} + # %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 diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index 66c4034781..f33e4959f9 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -1,3 +1,4 @@ +require 'active_support/inflector/methods' # String inflections define new methods on the String class to transform names for different purposes. # For instance, you can figure out the name of a database from the name of a class. # diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb index 16ccd36458..0b974f5e0a 100644 --- a/activesupport/lib/active_support/core_ext/string/multibyte.rb +++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb @@ -12,11 +12,11 @@ class String # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsuled string. # # name = 'Claus Müller' - # name.reverse #=> "rell??M sualC" - # name.length #=> 13 + # name.reverse # => "rell??M sualC" + # name.length # => 13 # - # name.mb_chars.reverse.to_s #=> "rellüM sualC" - # name.mb_chars.length #=> 12 + # name.mb_chars.reverse.to_s # => "rellüM sualC" + # name.mb_chars.length # => 12 # # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware. This means that # it becomes easy to run one version of your code on multiple Ruby versions. @@ -26,7 +26,7 @@ class String # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows # method chaining on the result of any of these methods. # - # name.mb_chars.reverse.length #=> 12 + # name.mb_chars.reverse.length # => 12 # # == Interoperability and configuration # diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb index b22d0a6941..deb33ab702 100644 --- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb +++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb @@ -5,11 +5,11 @@ module ActiveSupport class DeprecationProxy #:nodoc: def self.new(*args, &block) object = args.first - + return object unless object super end - + instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$/ } # Don't give a deprecation warning on inspect since test/unit and error diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index 51c2a0edac..019fb2df06 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -11,7 +11,7 @@ module ActiveSupport #:nodoc: # String methods are proxied through the Chars object, and can be accessed through the +mb_chars+ method. Methods # which would normally return a String object now return a Chars object so methods can be chained. # - # "The Perfect String ".mb_chars.downcase.strip.normalize #=> "the perfect string" + # "The Perfect String ".mb_chars.downcase.strip.normalize # => "the perfect string" # # Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made. # If certain methods do explicitly check the class, call +to_s+ before you pass chars objects to them. @@ -83,12 +83,13 @@ module ActiveSupport #:nodoc: include Comparable - # Returns <tt>-1</tt>, <tt>0</tt> or <tt>+1</tt> depending on whether the Chars object is to be sorted before, - # equal or after the object on the right side of the operation. It accepts any object that implements +to_s+. - # See <tt>String#<=></tt> for more details. + # Returns -1, 0, or 1, depending on whether the Chars object is to be sorted before, + # equal or after the object on the right side of the operation. It accepts any object + # that implements +to_s+: # - # Example: - # 'é'.mb_chars <=> 'ü'.mb_chars #=> -1 + # 'é'.mb_chars <=> 'ü'.mb_chars # => -1 + # + # See <tt>String#<=></tt> for more details. def <=>(other) @wrapped_string <=> other.to_s end @@ -103,7 +104,7 @@ module ActiveSupport #:nodoc: # Returns a new Chars object containing the _other_ object concatenated to the string. # # Example: - # ('Café'.mb_chars + ' périferôl').to_s #=> "Café périferôl" + # ('Café'.mb_chars + ' périferôl').to_s # => "Café périferôl" def +(other) chars(@wrapped_string + other) end @@ -111,7 +112,7 @@ module ActiveSupport #:nodoc: # Like <tt>String#=~</tt> only it returns the character offset (in codepoints) instead of the byte offset. # # Example: - # 'Café périferôl'.mb_chars =~ /ô/ #=> 12 + # 'Café périferôl'.mb_chars =~ /ô/ # => 12 def =~(other) translate_offset(@wrapped_string =~ other) end @@ -119,7 +120,7 @@ module ActiveSupport #:nodoc: # Inserts the passed string at specified codepoint offsets. # # Example: - # 'Café'.mb_chars.insert(4, ' périferôl').to_s #=> "Café périferôl" + # 'Café'.mb_chars.insert(4, ' périferôl').to_s # => "Café périferôl" def insert(offset, fragment) unpacked = Unicode.u_unpack(@wrapped_string) unless offset > unpacked.length @@ -135,7 +136,7 @@ module ActiveSupport #:nodoc: # Returns +true+ if contained string contains _other_. Returns +false+ otherwise. # # Example: - # 'Café'.mb_chars.include?('é') #=> true + # 'Café'.mb_chars.include?('é') # => true def include?(other) # We have to redefine this method because Enumerable defines it. @wrapped_string.include?(other) @@ -144,8 +145,8 @@ module ActiveSupport #:nodoc: # Returns the position _needle_ in the string, counting in codepoints. Returns +nil+ if _needle_ isn't found. # # Example: - # 'Café périferôl'.mb_chars.index('ô') #=> 12 - # 'Café périferôl'.mb_chars.index(/\w/u) #=> 0 + # 'Café périferôl'.mb_chars.index('ô') # => 12 + # 'Café périferôl'.mb_chars.index(/\w/u) # => 0 def index(needle, offset=0) wrapped_offset = first(offset).wrapped_string.length index = @wrapped_string.index(needle, wrapped_offset) @@ -157,8 +158,8 @@ module ActiveSupport #:nodoc: # string. Returns +nil+ if _needle_ isn't found. # # Example: - # 'Café périferôl'.mb_chars.rindex('é') #=> 6 - # 'Café périferôl'.mb_chars.rindex(/\w/u) #=> 13 + # 'Café périferôl'.mb_chars.rindex('é') # => 6 + # 'Café périferôl'.mb_chars.rindex(/\w/u) # => 13 def rindex(needle, offset=nil) offset ||= length wrapped_offset = first(offset).wrapped_string.length @@ -190,7 +191,7 @@ module ActiveSupport #:nodoc: # Returns the codepoint of the first character in the string. # # Example: - # 'こんにちは'.mb_chars.ord #=> 12371 + # 'こんにちは'.mb_chars.ord # => 12371 def ord Unicode.u_unpack(@wrapped_string)[0] end @@ -200,10 +201,10 @@ module ActiveSupport #:nodoc: # Example: # # "¾ cup".mb_chars.rjust(8).to_s - # #=> " ¾ cup" + # # => " ¾ cup" # # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace - # #=> " ¾ cup" + # # => " ¾ cup" def rjust(integer, padstr=' ') justify(integer, :right, padstr) end @@ -213,10 +214,10 @@ module ActiveSupport #:nodoc: # Example: # # "¾ cup".mb_chars.rjust(8).to_s - # #=> "¾ cup " + # # => "¾ cup " # # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace - # #=> "¾ cup " + # # => "¾ cup " def ljust(integer, padstr=' ') justify(integer, :left, padstr) end @@ -226,10 +227,10 @@ module ActiveSupport #:nodoc: # Example: # # "¾ cup".mb_chars.center(8).to_s - # #=> " ¾ cup " + # # => " ¾ cup " # # "¾ cup".mb_chars.center(8, " ").to_s # Use non-breaking whitespace - # #=> " ¾ cup " + # # => " ¾ cup " def center(integer, padstr=' ') justify(integer, :center, padstr) end @@ -244,7 +245,7 @@ module ActiveSupport #:nodoc: # instances instead of String. This makes chaining methods easier. # # Example: - # 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } #=> ["CAF", " P", "RIFERÔL"] + # 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"] def split(*args) @wrapped_string.split(*args).map { |i| i.mb_chars } end @@ -256,12 +257,12 @@ module ActiveSupport #:nodoc: # s = "Müller" # s.mb_chars[2] = "e" # Replace character with offset 2 # s - # #=> "Müeler" + # # => "Müeler" # # s = "Müller" # s.mb_chars[1, 2] = "ö" # Replace 2 characters at character offset 1 # s - # #=> "Möler" + # # => "Möler" def []=(*args) replace_by = args.pop # Indexed replace with regular expressions already works @@ -292,7 +293,7 @@ module ActiveSupport #:nodoc: # Reverses all characters in the string. # # Example: - # 'Café'.mb_chars.reverse.to_s #=> 'éfaC' + # 'Café'.mb_chars.reverse.to_s # => 'éfaC' def reverse chars(Unicode.g_unpack(@wrapped_string).reverse.flatten.pack('U*')) end @@ -301,7 +302,7 @@ module ActiveSupport #:nodoc: # character. # # Example: - # 'こんにちは'.mb_chars.slice(2..3).to_s #=> "にち" + # 'こんにちは'.mb_chars.slice(2..3).to_s # => "にち" def slice(*args) if args.size > 2 raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" # Do as if we were native @@ -330,7 +331,7 @@ module ActiveSupport #:nodoc: # # Example: # s = 'こんにちは' - # s.mb_chars.limit(7) #=> "こに" + # s.mb_chars.limit(7) # => "こに" def limit(limit) slice(0...translate_offset(limit)) end @@ -338,7 +339,7 @@ module ActiveSupport #:nodoc: # Convert characters in the string to uppercase. # # Example: - # 'Laurent, où sont les tests ?'.mb_chars.upcase.to_s #=> "LAURENT, OÙ SONT LES TESTS ?" + # 'Laurent, où sont les tests ?'.mb_chars.upcase.to_s # => "LAURENT, OÙ SONT LES TESTS ?" def upcase chars(Unicode.apply_mapping @wrapped_string, :uppercase_mapping) end @@ -346,7 +347,7 @@ module ActiveSupport #:nodoc: # Convert characters in the string to lowercase. # # Example: - # 'VĚDA A VÝZKUM'.mb_chars.downcase.to_s #=> "věda a výzkum" + # 'VĚDA A VÝZKUM'.mb_chars.downcase.to_s # => "věda a výzkum" def downcase chars(Unicode.apply_mapping @wrapped_string, :lowercase_mapping) end @@ -354,7 +355,7 @@ module ActiveSupport #:nodoc: # Converts the first character to uppercase and the remainder to lowercase. # # Example: - # 'über'.mb_chars.capitalize.to_s #=> "Über" + # 'über'.mb_chars.capitalize.to_s # => "Über" def capitalize (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase end @@ -382,8 +383,8 @@ module ActiveSupport #:nodoc: # Performs canonical decomposition on all the characters. # # Example: - # 'é'.length #=> 2 - # 'é'.mb_chars.decompose.to_s.length #=> 3 + # 'é'.length # => 2 + # 'é'.mb_chars.decompose.to_s.length # => 3 def decompose chars(Unicode.decompose_codepoints(:canonical, Unicode.u_unpack(@wrapped_string)).pack('U*')) end @@ -391,8 +392,8 @@ module ActiveSupport #:nodoc: # Performs composition on all the characters. # # Example: - # 'é'.length #=> 3 - # 'é'.mb_chars.compose.to_s.length #=> 2 + # 'é'.length # => 3 + # 'é'.mb_chars.compose.to_s.length # => 2 def compose chars(Unicode.compose_codepoints(Unicode.u_unpack(@wrapped_string)).pack('U*')) end @@ -400,8 +401,8 @@ module ActiveSupport #:nodoc: # Returns the number of grapheme clusters in the string. # # Example: - # 'क्षि'.mb_chars.length #=> 4 - # 'क्षि'.mb_chars.g_length #=> 3 + # 'क्षि'.mb_chars.length # => 4 + # 'क्षि'.mb_chars.g_length # => 3 def g_length Unicode.g_unpack(@wrapped_string).length end diff --git a/activesupport/lib/active_support/multibyte/unicode.rb b/activesupport/lib/active_support/multibyte/unicode.rb index 3d80f5fa58..1139783b65 100644 --- a/activesupport/lib/active_support/multibyte/unicode.rb +++ b/activesupport/lib/active_support/multibyte/unicode.rb @@ -64,7 +64,7 @@ module ActiveSupport # valid UTF-8. # # Example: - # Unicode.u_unpack('Café') #=> [67, 97, 102, 233] + # Unicode.u_unpack('Café') # => [67, 97, 102, 233] def u_unpack(string) begin string.unpack 'U*' @@ -85,8 +85,8 @@ module ActiveSupport # Unpack the string at grapheme boundaries. Returns a list of character lists. # # Example: - # Unicode.g_unpack('क्षि') #=> [[2325, 2381], [2359], [2367]] - # Unicode.g_unpack('Café') #=> [[67], [97], [102], [233]] + # Unicode.g_unpack('क्षि') # => [[2325, 2381], [2359], [2367]] + # Unicode.g_unpack('Café') # => [[67], [97], [102], [233]] def g_unpack(string) codepoints = u_unpack(string) unpacked = [] @@ -120,7 +120,7 @@ module ActiveSupport # Reverse operation of g_unpack. # # Example: - # Unicode.g_pack(Unicode.g_unpack('क्षि')) #=> 'क्षि' + # Unicode.g_pack(Unicode.g_unpack('क्षि')) # => 'क्षि' def g_pack(unpacked) (unpacked.flatten).pack('U*') end diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb index ca9f5ae1ac..fd79188ba4 100644 --- a/activesupport/lib/active_support/notifications.rb +++ b/activesupport/lib/active_support/notifications.rb @@ -22,9 +22,9 @@ module ActiveSupport # end # # event = @events.first - # event.name #=> :render - # event.duration #=> 10 (in milliseconds) - # event.payload #=> { :extra => :information } + # event.name # => :render + # event.duration # => 10 (in milliseconds) + # event.payload # => { :extra => :information } # # When subscribing to Notifications, you can pass a pattern, to only consume # events that match the pattern: diff --git a/activesupport/lib/active_support/secure_random.rb b/activesupport/lib/active_support/secure_random.rb index cfbce4d754..73344498cb 100644 --- a/activesupport/lib/active_support/secure_random.rb +++ b/activesupport/lib/active_support/secure_random.rb @@ -26,25 +26,25 @@ module ActiveSupport # == Example # # # random hexadecimal string. - # p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362" - # p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559" - # p SecureRandom.hex(11) #=> "6aca1b5c58e4863e6b81b8" - # p SecureRandom.hex(12) #=> "94b2fff3e7fd9b9c391a2306" - # p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23" + # p SecureRandom.hex(10) # => "52750b30ffbc7de3b362" + # p SecureRandom.hex(10) # => "92b15d6c8dc4beb5f559" + # p SecureRandom.hex(11) # => "6aca1b5c58e4863e6b81b8" + # p SecureRandom.hex(12) # => "94b2fff3e7fd9b9c391a2306" + # p SecureRandom.hex(13) # => "39b290146bea6ce975c37cfc23" # ... # # # random base64 string. - # p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA==" - # p SecureRandom.base64(10) #=> "9b0nsevdwNuM/w==" - # p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg==" - # p SecureRandom.base64(11) #=> "l7XEiFja+8EKEtY=" - # p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8" - # p SecureRandom.base64(13) #=> "vKLJ0tXBHqQOuIcSIg==" + # p SecureRandom.base64(10) # => "EcmTPZwWRAozdA==" + # p SecureRandom.base64(10) # => "9b0nsevdwNuM/w==" + # p SecureRandom.base64(10) # => "KO1nIU+p9DKxGg==" + # p SecureRandom.base64(11) # => "l7XEiFja+8EKEtY=" + # p SecureRandom.base64(12) # => "7kJSM/MzBJI+75j8" + # p SecureRandom.base64(13) # => "vKLJ0tXBHqQOuIcSIg==" # ... # # # random binary string. - # p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301" - # p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337" + # p SecureRandom.random_bytes(10) # => "\016\t{\370g\310pbr\301" + # p SecureRandom.random_bytes(10) # => "\323U\030TO\234\357\020\a\337" # ... module SecureRandom # SecureRandom.random_bytes generates a random binary string. diff --git a/activesupport/lib/active_support/version.rb b/activesupport/lib/active_support/version.rb index 52612c27cb..9d2cf13260 100644 --- a/activesupport/lib/active_support/version.rb +++ b/activesupport/lib/active_support/version.rb @@ -3,7 +3,7 @@ module ActiveSupport MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 212c1f82a8..b79a7bbaec 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -7,6 +7,49 @@ class CacheKeyTest < ActiveSupport::TestCase assert_equal '1/2/true', ActiveSupport::Cache.expand_cache_key([1, '2', true]) assert_equal 'name/1/2/true', ActiveSupport::Cache.expand_cache_key([1, '2', true], :name) end + + def test_expand_cache_key_with_rails_cache_id + begin + ENV['RAILS_CACHE_ID'] = 'c99' + assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo) + assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key([:foo]) + assert_equal 'c99/c99/foo/c99/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar]) + assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key(:foo, :nm) + assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo], :nm) + assert_equal 'nm/c99/c99/foo/c99/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar], :nm) + ensure + ENV['RAILS_CACHE_ID'] = nil + end + end + + def test_expand_cache_key_with_rails_app_version + begin + ENV['RAILS_APP_VERSION'] = 'rails3' + assert_equal 'rails3/foo', ActiveSupport::Cache.expand_cache_key(:foo) + ensure + ENV['RAILS_APP_VERSION'] = nil + end + end + + def test_expand_cache_key_rails_cache_id_should_win_over_rails_app_version + begin + ENV['RAILS_CACHE_ID'] = 'c99' + ENV['RAILS_APP_VERSION'] = 'rails3' + assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo) + ensure + ENV['RAILS_CACHE_ID'] = nil + ENV['RAILS_APP_VERSION'] = nil + end + end + + def test_respond_to_cache_key + key = 'foo' + def key.cache_key + :foo_key + end + assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key(key) + end + end class CacheStoreSettingTest < ActiveSupport::TestCase diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb index 54376deee5..009a254c64 100644 --- a/activesupport/test/core_ext/array_ext_test.rb +++ b/activesupport/test/core_ext/array_ext_test.rb @@ -398,6 +398,18 @@ class ArrayWrapperTests < Test::Unit::TestCase def method_missing(*a) @target.send(*a) end end + class DoubtfulToAry + def to_ary + :not_an_array + end + end + + class NilToAry + def to_ary + nil + end + end + def test_array ary = %w(foo bar) assert_same ary, Array.wrap(ary) @@ -438,4 +450,12 @@ class ArrayWrapperTests < Test::Unit::TestCase o = Struct.new(:foo).new(123) assert_equal [o], Array.wrap(o) end + + def test_wrap_returns_nil_if_to_ary_returns_nil + assert_nil Array.wrap(NilToAry.new) + end + + def test_wrap_does_not_complain_if_to_ary_does_not_return_an_array + assert_equal DoubtfulToAry.new.to_ary, Array.wrap(DoubtfulToAry.new) + end end diff --git a/activesupport/test/deprecation/proxy_wrappers_test.rb b/activesupport/test/deprecation/proxy_wrappers_test.rb index c507eff38e..aa887f274d 100644 --- a/activesupport/test/deprecation/proxy_wrappers_test.rb +++ b/activesupport/test/deprecation/proxy_wrappers_test.rb @@ -4,19 +4,19 @@ require 'active_support/deprecation' class ProxyWrappersTest < Test::Unit::TestCase Waffles = false NewWaffles = :hamburgers - + def test_deprecated_object_proxy_doesnt_wrap_falsy_objects proxy = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(nil, "message") assert !proxy end - + def test_deprecated_instance_variable_proxy_doesnt_wrap_falsy_objects proxy = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(nil, :waffles) assert !proxy end - + def test_deprecated_constant_proxy_doesnt_wrap_falsy_objects proxy = ActiveSupport::Deprecation::DeprecatedConstantProxy.new(Waffles, NewWaffles) assert !proxy end -end
\ No newline at end of file +end diff --git a/activesupport/test/load_paths_test.rb b/activesupport/test/load_paths_test.rb index c8bc1a2ffe..36e3726a02 100644 --- a/activesupport/test/load_paths_test.rb +++ b/activesupport/test/load_paths_test.rb @@ -10,6 +10,6 @@ class LoadPathsTest < Test::Unit::TestCase } load_paths_count[File.expand_path('../../lib', __FILE__)] -= 1 - assert_equal [], load_paths_count.select { |k, v| v > 1 }, $LOAD_PATH.inspect + assert load_paths_count.select { |k, v| v > 1 }.empty?, $LOAD_PATH.inspect end end diff --git a/install.rb b/install.rb new file mode 100644 index 0000000000..05bba27a14 --- /dev/null +++ b/install.rb @@ -0,0 +1,11 @@ +version = ARGV.pop + +%w( activesupport activemodel activerecord activeresource actionpack actionmailer railties ).each do |framework| + puts "Installing #{framework}..." + `cd #{framework} && gem build #{framework}.gemspec && gem install #{framework}-#{version}.gem --no-ri --no-rdoc && rm #{framework}-#{version}.gem` +end + +puts "Installing Rails..." +`gem build rails.gemspec` +`gem install rails-#{version}.gem --no-ri --no-rdoc ` +`rm rails-#{version}.gem`
\ No newline at end of file diff --git a/rails.gemspec b/rails.gemspec index db13653ebc..00dde1934d 100644 --- a/rails.gemspec +++ b/rails.gemspec @@ -25,5 +25,5 @@ Gem::Specification.new do |s| s.add_dependency('activeresource', version) s.add_dependency('actionmailer', version) s.add_dependency('railties', version) - s.add_dependency('bundler', '>= 1.0.0.beta.10') + s.add_dependency('bundler', '>= 1.0.0.rc.1') end diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 3cd9647799..fc1ec340c7 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,4 +1,4 @@ -*Rails 3.0.0 [Release Candidate] (unreleased)* +*Rails 3.0.0 [release candidate] (July 26th, 2010)* * Application generation: --skip-testunit and --skip-activerecord become --skip-test-unit and --skip-active-record respectively. [fxn] diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 6ee7a4220b..fcf4ae29ba 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -2214,7 +2214,14 @@ NOTE: Defined in +active_support/core_ext/array/conversions.rb+. h4. Wrapping -The class method +Array.wrap+ behaves like the function +Array()+ except that it does not try to call +to_a+ on its argument. That changes the behavior for enumerables: +The class method +Array.wrap+ behaves like the function +Array()+ except: + +* If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt> moves on to try +to_a+ if the returned value is +nil+, but <tt>Arraw.wrap</tt> returns such a +nil+ right away. +* If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt> raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value. +* It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array. + + + that it does not try to call +to_a+ on its argument. That changes the behavior for enumerables: <ruby> Array.wrap(:foo => :bar) # => [{:foo => :bar}] diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 3f9bca0bd6..6622cfdd2f 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -205,6 +205,7 @@ module Rails middleware.use ::ActionDispatch::ParamsParser middleware.use ::Rack::MethodOverride middleware.use ::ActionDispatch::Head + middleware.use ::ActionDispatch::BestStandardsSupport if config.action_dispatch.best_standards_support end end diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb index b9353ba336..60a93c9848 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -70,4 +70,4 @@ In addition to those, there are: All commands can be run with -h for more information. EOT -end
\ No newline at end of file +end diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 2f465670cf..521ed95447 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -50,4 +50,4 @@ module Rails end end end -end
\ No newline at end of file +end diff --git a/railties/lib/rails/generators/active_model.rb b/railties/lib/rails/generators/active_model.rb index fe6321af30..4b828340d2 100644 --- a/railties/lib/rails/generators/active_model.rb +++ b/railties/lib/rails/generators/active_model.rb @@ -9,16 +9,16 @@ module Rails # For example: # # ActiveRecord::Generators::ActiveModel.find(Foo, "params[:id]") - # #=> "Foo.find(params[:id])" + # # => "Foo.find(params[:id])" # # Datamapper::Generators::ActiveModel.find(Foo, "params[:id]") - # #=> "Foo.get(params[:id])" + # # => "Foo.get(params[:id])" # # On initialization, the ActiveModel accepts the instance name that will # receive the calls: # # builder = ActiveRecord::Generators::ActiveModel.new "@foo" - # builder.save #=> "@foo.save" + # builder.save # => "@foo.save" # # The only exception in ActiveModel for ActiveRecord is the use of self.build # instead of self.new. diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb index 36bc542ffe..3376b422cb 100644 --- a/railties/lib/rails/generators/test_case.rb +++ b/railties/lib/rails/generators/test_case.rb @@ -68,7 +68,7 @@ module Rails # Captures the given stream and returns it: # # stream = capture(:stdout){ puts "Cool" } - # stream #=> "Cool\n" + # stream # => "Cool\n" # def capture(stream) begin diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb index 96f2d9296e..6cbd1f21c0 100644 --- a/railties/lib/rails/info.rb +++ b/railties/lib/rails/info.rb @@ -88,7 +88,7 @@ module Rails end property 'Middleware' do - Rails.configuration.middleware.active.map(&:inspect) + Rails.configuration.middleware.map(&:inspect) end # The application's location on the filesystem. diff --git a/railties/lib/rails/script_rails_loader.rb b/railties/lib/rails/script_rails_loader.rb index 8fbd3bf492..91672e5d81 100644 --- a/railties/lib/rails/script_rails_loader.rb +++ b/railties/lib/rails/script_rails_loader.rb @@ -7,6 +7,7 @@ module Rails def self.exec_script_rails! cwd = Dir.pwd + return unless in_rails_application? || in_rails_application_subdirectory? exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? Dir.chdir("..") do # Recurse in a chdir block: if the search fails we want to be sure @@ -18,7 +19,7 @@ module Rails end def self.in_rails_application? - File.exists?(SCRIPT_RAILS) || in_rails_application_subdirectory? + File.exists?(SCRIPT_RAILS) end def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd)) diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake index e7bd0c38dc..443dacd739 100644 --- a/railties/lib/rails/tasks/framework.rake +++ b/railties/lib/rails/tasks/framework.rake @@ -54,7 +54,7 @@ namespace :rails do namespace :update do def invoke_from_app_generator(method) - app_generator.invoke(method) + app_generator.send(method) end def app_generator diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb index 34d96fd0f3..c5d1d02bc1 100644 --- a/railties/lib/rails/version.rb +++ b/railties/lib/rails/version.rb @@ -3,7 +3,7 @@ module Rails MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index db9f06be5c..1f127cee78 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -34,7 +34,8 @@ module ApplicationTests "ActionDispatch::Flash", "ActionDispatch::ParamsParser", "Rack::MethodOverride", - "ActionDispatch::Head" + "ActionDispatch::Head", + "ActionDispatch::BestStandardsSupport" ], middleware end diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index f0268164d0..a10a39ef40 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -40,6 +40,7 @@ module ApplicationTests get '/foo' assert_equal 'foo', last_response.body + assert_equal "IE=Edge,chrome=1", last_response.headers["X-UA-Compatible"] end test "simple controller with helper" do diff --git a/version.rb b/version.rb index 34d96fd0f3..c5d1d02bc1 100644 --- a/version.rb +++ b/version.rb @@ -3,7 +3,7 @@ module Rails MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta4" + BUILD = "rc" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end |