Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'upstream/master'

  • Loading branch information...
commit 9bd6b4178ee774d34fe7809c461903e5f383e8d7 2 parents fa3268d + 02691d3
@iaddict authored
Showing with 1,009 additions and 473 deletions.
  1. +12 −0 .travis.yml
  2. +9 −10 Gemfile
  3. +2 −0  actionpack/CHANGELOG
  4. +1 −1  actionpack/lib/action_controller/metal/request_forgery_protection.rb
  5. +2 −1  actionpack/lib/action_dispatch/http/mime_negotiation.rb
  6. +1 −1  actionpack/lib/action_view/helpers/asset_tag_helper.rb
  7. +47 −47 actionpack/lib/action_view/helpers/date_helper.rb
  8. +39 −6 actionpack/lib/action_view/helpers/form_helper.rb
  9. +1 −1  actionpack/lib/action_view/helpers/form_tag_helper.rb
  10. +2 −0  actionpack/lib/action_view/helpers/number_helper.rb
  11. +1 −1  actionpack/lib/action_view/helpers/translation_helper.rb
  12. +4 −4 actionpack/lib/action_view/helpers/url_helper.rb
  13. +27 −22 actionpack/lib/action_view/renderer/partial_renderer.rb
  14. +12 −10 actionpack/lib/sprockets/assets.rake
  15. +2 −0  actionpack/lib/sprockets/helpers/rails_helper.rb
  16. +2 −2 actionpack/lib/sprockets/railtie.rb
  17. +14 −0 actionpack/test/controller/render_test.rb
  18. +6 −0 actionpack/test/dispatch/request_test.rb
  19. +1 −1  actionpack/test/template/asset_tag_helper_test.rb
  20. +3 −6 actionpack/test/template/sprockets_helper_test.rb
  21. +27 −0 activemodel/README.rdoc
  22. +1 −1  activemodel/lib/active_model/dirty.rb
  23. +10 −0 activerecord/CHANGELOG
  24. +2 −1  activerecord/lib/active_record.rb
  25. +1 −1  activerecord/lib/active_record/associations/collection_association.rb
  26. +7 −6 activerecord/lib/active_record/base.rb
  27. +26 −0 activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
  28. +5 −0 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
  29. +2 −0  activerecord/lib/active_record/migration.rb
  30. +1 −1  activerecord/lib/active_record/nested_attributes.rb
  31. +2 −1  activerecord/lib/active_record/railties/databases.rake
  32. +1 −1  activerecord/lib/active_record/relation/finder_methods.rb
  33. +1 −0  activerecord/lib/active_record/relation/query_methods.rb
  34. +0 −6 activerecord/test/cases/adapter_test.rb
  35. +10 −0 activerecord/test/cases/adapters/mysql/connection_test.rb
  36. +14 −0 activerecord/test/cases/adapters/postgresql/connection_test.rb
  37. +1 −1  activerecord/test/cases/adapters/sqlite3/quoting_test.rb
  38. +12 −0 activerecord/test/cases/associations/eager_test.rb
  39. +20 −24 activerecord/test/cases/base_test.rb
  40. +34 −0 activerecord/test/cases/connection_management_test.rb
  41. +2 −2 activerecord/test/cases/identity_map_test.rb
  42. +2 −2 activerecord/test/cases/invalid_date_test.rb
  43. +5 −0 activerecord/test/cases/nested_attributes_test.rb
  44. +4 −0 activerecord/test/cases/relations_test.rb
  45. +1 −1  activeresource/lib/active_resource/base.rb
  46. +1 −1  activeresource/lib/active_resource/http_mock.rb
  47. +3 −0  activesupport/CHANGELOG
  48. +1 −1  activesupport/lib/active_support/cache/file_store.rb
  49. +1 −7 activesupport/lib/active_support/core_ext/class/attribute.rb
  50. +16 −6 activesupport/lib/active_support/core_ext/enumerable.rb
  51. +7 −1 activesupport/lib/active_support/core_ext/object/blank.rb
  52. +1 −0  activesupport/lib/active_support/core_ext/string/conversions.rb
  53. +1 −1  activesupport/lib/active_support/core_ext/string/multibyte.rb
  54. +2 −2 activesupport/lib/active_support/deprecation/behaviors.rb
  55. +4 −2 activesupport/lib/active_support/inflector/methods.rb
  56. +1 −2  activesupport/lib/active_support/multibyte/chars.rb
  57. +1 −0  activesupport/lib/active_support/multibyte/unicode.rb
  58. +1 −1  activesupport/lib/active_support/ordered_hash.rb
  59. +7 −0 activesupport/test/caching_test.rb
  60. +12 −7 activesupport/test/core_ext/duplicable_test.rb
  61. +58 −26 activesupport/test/core_ext/enumerable_test.rb
  62. +1 −1  activesupport/test/core_ext/string_ext_test.rb
  63. +1 −1  activesupport/test/json/decoding_test.rb
  64. +142 −0 ci/travis.rb
  65. +2 −6 load_paths.rb
  66. +1 −1  railties/guides/source/action_mailer_basics.textile
  67. +2 −2 railties/guides/source/action_view_overview.textile
  68. +1 −0  railties/guides/source/active_record_querying.textile
  69. +3 −3 railties/guides/source/active_record_validations_callbacks.textile
  70. +4 −2 railties/guides/source/active_support_core_extensions.textile
  71. +1 −1  railties/guides/source/api_documentation_guidelines.textile
  72. +159 −78 railties/guides/source/asset_pipeline.textile
  73. +1 −1  railties/guides/source/association_basics.textile
  74. +6 −6 railties/guides/source/caching_with_rails.textile
  75. +4 −0 railties/guides/source/command_line.textile
  76. +5 −3 railties/guides/source/configuring.textile
  77. +11 −4 railties/guides/source/form_helpers.textile
  78. +21 −13 railties/guides/source/getting_started.textile
  79. +1 −1  railties/guides/source/initialization.textile
  80. +1 −1  railties/guides/source/layouts_and_rendering.textile
  81. +28 −13 railties/guides/source/migrations.textile
  82. +3 −3 railties/guides/source/plugins.textile
  83. +4 −8 railties/guides/source/rails_application_templates.textile
  84. +50 −50 railties/guides/source/routing.textile
  85. +5 −5 railties/guides/source/security.textile
  86. +1 −1  railties/lib/rails.rb
  87. +1 −1  railties/lib/rails/application.rb
  88. +1 −1  railties/lib/rails/commands.rb
  89. +35 −31 railties/lib/rails/engine.rb
  90. +1 −1  railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
  91. +9 −9 railties/lib/rails/paths.rb
  92. +3 −3 railties/lib/rails/tasks/documentation.rake
  93. +3 −3 railties/lib/rails/tasks/framework.rake
  94. +2 −2 railties/lib/rails/test_unit/testing.rake
View
12 .travis.yml
@@ -0,0 +1,12 @@
+script: 'ci/travis.rb'
+notifications:
+ disabled: true
+rvm:
+ - 1.8.7
+ - 1.9.2
+env:
+ - "GEM=railties"
+ - "GEM=ap,am,amo,ares,as"
+ - "GEM=ar:mysql"
+ - "GEM=ar:mysql2"
+ - "GEM=ar:sqlite3"
View
19 Gemfile
@@ -9,9 +9,6 @@ else
end
gem "jquery-rails"
-gem "coffee-script"
-gem "sass"
-
# This needs to be with require false to avoid
# it being automatically loaded by sprockets
gem "uglifier", ">= 1.0.0", :require => false
@@ -31,13 +28,19 @@ gem "memcache-client", ">= 1.8.5"
platforms :mri_18 do
gem "system_timer"
- gem "ruby-debug", ">= 0.10.3"
+ gem "ruby-debug", ">= 0.10.3" unless ENV['TRAVIS']
gem "json"
end
platforms :mri_19 do
# TODO: Remove the conditional when ruby-debug19 supports Ruby >= 1.9.3
- gem "ruby-debug19", :require => "ruby-debug" if RUBY_VERSION < "1.9.3"
+ gem "ruby-debug19", :require => "ruby-debug" unless RUBY_VERSION > "1.9.2" || ENV['TRAVIS']
+end
+
+platforms :mri do
+ group :test do
+ gem "ruby-prof" if RUBY_VERSION < "1.9.3"
+ end
end
platforms :ruby do
@@ -48,15 +51,11 @@ platforms :ruby do
gem "yajl-ruby"
gem "nokogiri", ">= 1.4.5"
- group :test do
- gem "ruby-prof" if RUBY_VERSION < "1.9.3"
-
- end
# AR
gem "sqlite3", "~> 1.3.3"
group :db do
- gem "pg", ">= 0.11.0"
+ gem "pg", ">= 0.11.0" unless ENV['TRAVIS'] # once pg is on travis this can be removed
gem "mysql", ">= 2.8.1"
gem "mysql2", ">= 0.3.6"
end
View
2  actionpack/CHANGELOG
@@ -30,6 +30,8 @@
*Rails 3.1.0 (unreleased)*
+* The submit form helper does not generate an id "object_name_id" anymore. [fbrusatti]
+
* Make sure respond_with with :js tries to render a template in all cases [José Valim]
* json_escape will now return a SafeBuffer string if it receives SafeBuffer string [tenderlove]
View
2  actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -79,7 +79,7 @@ def verify_authenticity_token
end
end
- # This is the method that defines the application behaviour when a request is found to be unverified.
+ # This is the method that defines the application behavior when a request is found to be unverified.
# By default, \Rails resets the session when it finds an unverified request.
def handle_unverified_request
reset_session
View
3  actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -98,7 +98,8 @@ def negotiate_mime(order)
BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
def valid_accept_header
- xhr? || (accept && accept !~ BROWSER_LIKE_ACCEPTS)
+ (xhr? && (accept || content_mime_type)) ||
+ (accept && accept !~ BROWSER_LIKE_ACCEPTS)
end
def use_accept_header
View
2  actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -154,7 +154,7 @@ module Helpers #:nodoc:
# "/release-#{RELEASE_NUMBER}#{asset_path}"
# }
#
- # This example would cause the following behaviour on all servers no
+ # This example would cause the following behavior on all servers no
# matter when they were deployed:
#
# image_tag("rails.png")
View
94 actionpack/lib/action_view/helpers/date_helper.rb
@@ -8,8 +8,8 @@ module ActionView
module Helpers
# = Action View Date Helpers
#
- # The Date Helper primarily creates select/option tags for different kinds of dates and date elements. All of the
- # select-type methods share a number of common options that are as follows:
+ # The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time
+ # elements. All of the select-type methods share a number of common options that are as follows:
#
# * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday"
# would give birthday[month] instead of date[month] if passed to the <tt>select_month</tt> method.
@@ -18,7 +18,7 @@ module Helpers
# the <tt>select_month</tt> method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead
# of "date[month]".
module DateHelper
- # Reports the approximate distance in time between two Time or Date objects or integers as seconds.
+ # Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds.
# Set <tt>include_seconds</tt> to true if you want more detailed approximations when distance < 1 min, 29 secs.
# Distances are reported based on the following table:
#
@@ -176,37 +176,37 @@ def time_ago_in_words(from_time, include_seconds = false)
# NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
#
# ==== Examples
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute.
- # date_select("post", "written_on")
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute.
+ # date_select("article", "written_on")
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute,
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
# # with the year in the year drop down box starting at 1995.
- # date_select("post", "written_on", :start_year => 1995)
+ # date_select("article", "written_on", :start_year => 1995)
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute,
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
# # with the year in the year drop down box starting at 1995, numbers used for months instead of words,
# # and without a day select box.
- # date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true,
+ # date_select("article", "written_on", :start_year => 1995, :use_month_numbers => true,
# :discard_day => true, :include_blank => true)
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
# # with the fields ordered as day, month, year rather than month, day, year.
- # date_select("post", "written_on", :order => [:day, :month, :year])
+ # date_select("article", "written_on", :order => [:day, :month, :year])
#
# # Generates a date select that when POSTed is stored in the user variable, in the birthday attribute
# # lacking a year field.
# date_select("user", "birthday", :order => [:month, :day])
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
# # which is initially set to the date 3 days from the current date
- # date_select("post", "written_on", :default => 3.days.from_now)
+ # date_select("article", "written_on", :default => 3.days.from_now)
#
# # Generates a date select that when POSTed is stored in the credit_card variable, in the bill_due attribute
# # that will have a default day of 20.
# date_select("credit_card", "bill_due", :default => { :day => 20 })
#
# # Generates a date select with custom prompts.
- # date_select("post", "written_on", :prompt => { :day => 'Select day', :month => 'Select month', :year => 'Select year' })
+ # date_select("article", "written_on", :prompt => { :day => 'Select day', :month => 'Select month', :year => 'Select year' })
#
# The selects are prepared for multi-parameter assignment to an Active Record object.
#
@@ -228,20 +228,20 @@ def date_select(object_name, method, options = {}, html_options = {})
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
# ==== Examples
- # # Creates a time select tag that, when POSTed, will be stored in the post variable in the sunrise attribute.
- # time_select("post", "sunrise")
+ # # Creates a time select tag that, when POSTed, will be stored in the article variable in the sunrise attribute.
+ # time_select("article", "sunrise")
#
- # # Creates a time select tag with a seconds field that, when POSTed, will be stored in the post variables in
+ # # Creates a time select tag with a seconds field that, when POSTed, will be stored in the article variables in
# # the sunrise attribute.
- # time_select("post", "start_time", :include_seconds => true)
+ # time_select("article", "start_time", :include_seconds => true)
#
# # You can set the <tt>:minute_step</tt> to 15 which will give you: 00, 15, 30 and 45.
# time_select 'game', 'game_time', {:minute_step => 15}
#
# # Creates a time select tag with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
- # time_select("post", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
- # time_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
- # time_select("post", "written_on", :prompt => true) # generic prompts for all
+ # time_select("article", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
+ # time_select("article", "written_on", :prompt => {:hour => true}) # generic prompt for hours
+ # time_select("article", "written_on", :prompt => true) # generic prompts for all
#
# # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
# time_select 'game', 'game_time', {:ampm => true}
@@ -261,36 +261,36 @@ def time_select(object_name, method, options = {}, html_options = {})
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
# ==== Examples
- # # Generates a datetime select that, when POSTed, will be stored in the post variable in the written_on
+ # # Generates a datetime select that, when POSTed, will be stored in the article variable in the written_on
# # attribute.
- # datetime_select("post", "written_on")
+ # datetime_select("article", "written_on")
#
# # Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the
- # # post variable in the written_on attribute.
- # datetime_select("post", "written_on", :start_year => 1995)
+ # # article variable in the written_on attribute.
+ # datetime_select("article", "written_on", :start_year => 1995)
#
# # Generates a datetime select with a default value of 3 days from the current time that, when POSTed, will
# # be stored in the trip variable in the departing attribute.
# datetime_select("trip", "departing", :default => 3.days.from_now)
#
# # Generate a datetime select with hours in the AM/PM format
- # datetime_select("post", "written_on", :ampm => true)
+ # datetime_select("article", "written_on", :ampm => true)
#
- # # Generates a datetime select that discards the type that, when POSTed, will be stored in the post variable
+ # # Generates a datetime select that discards the type that, when POSTed, will be stored in the article variable
# # as the written_on attribute.
- # datetime_select("post", "written_on", :discard_type => true)
+ # datetime_select("article", "written_on", :discard_type => true)
#
# # Generates a datetime select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
- # datetime_select("post", "written_on", :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
- # datetime_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
- # datetime_select("post", "written_on", :prompt => true) # generic prompts for all
+ # datetime_select("article", "written_on", :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
+ # datetime_select("article", "written_on", :prompt => {:hour => true}) # generic prompt for hours
+ # datetime_select("article", "written_on", :prompt => true) # generic prompts for all
#
# The selects are prepared for multi-parameter assignment to an Active Record object.
def datetime_select(object_name, method, options = {}, html_options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_datetime_select_tag(options, html_options)
end
- # Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the
+ # Returns a set of html select-tags (one for year, month, day, hour, minute, and second) pre-selected with the
# +datetime+. It's also possible to explicitly set the order of the tags using the <tt>:order</tt> option with
# an array of symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order. If you do not
# supply a Symbol, it will be appended onto the <tt>:order</tt> passed in. You can also add
@@ -343,15 +343,15 @@ def select_datetime(datetime = Time.current, options = {}, html_options = {})
# Returns a set of html select-tags (one for year, month, and day) pre-selected with the +date+.
# It's possible to explicitly set the order of the tags using the <tt>:order</tt> option with an array of
- # symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order. If you do not supply a Symbol,
- # it will be appended onto the <tt>:order</tt> passed in.
+ # symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order.
+ # If the array passed to the <tt>:order</tt> option does not contain all the three symbols, all tags will be hidden.
#
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
# ==== Examples
- # my_date = Time.today + 6.days
+ # my_date = Time.now + 6.days
#
- # # Generates a date select that defaults to the date in my_date (six days afteri today).
+ # # Generates a date select that defaults to the date in my_date (six days after today).
# select_date(my_date)
#
# # Generates a date select that defaults to today (no specified date).
@@ -422,7 +422,7 @@ def select_time(datetime = Time.current, options = {}, html_options = {})
end
# Returns a select tag with options for each of the seconds 0 through 59 with the current second selected.
- # The <tt>second</tt> can also be substituted for a second number.
+ # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'second' by default.
#
# ==== Examples
@@ -440,7 +440,7 @@ def select_time(datetime = Time.current, options = {}, html_options = {})
#
# # Generates a select field for seconds with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
- # select_minute(14, :prompt => 'Choose seconds')
+ # select_second(14, :prompt => 'Choose seconds')
#
def select_second(datetime, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_second
@@ -448,21 +448,21 @@ def select_second(datetime, options = {}, html_options = {})
# Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected.
# Also can return a select tag with options by <tt>minute_step</tt> from 0 through 59 with the 00 minute
- # selected. The <tt>minute</tt> can also be substituted for a minute number.
+ # selected. The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'minute' by default.
#
# ==== Examples
# my_time = Time.now + 6.hours
#
- # # Generates a select field for minutes that defaults to the minutes for the time in my_tiime.
+ # # Generates a select field for minutes that defaults to the minutes for the time in my_time.
# select_minute(my_time)
#
# # Generates a select field for minutes that defaults to the number given.
# select_minute(14)
#
# # Generates a select field for minutes that defaults to the minutes for the time in my_time
- # # that is named 'stride' rather than 'second'.
- # select_minute(my_time, :field_name => 'stride')
+ # # that is named 'moment' rather than 'minute'.
+ # select_minute(my_time, :field_name => 'moment')
#
# # Generates a select field for minutes with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
@@ -473,7 +473,7 @@ def select_minute(datetime, options = {}, html_options = {})
end
# Returns a select tag with options for each of the hours 0 through 23 with the current hour selected.
- # The <tt>hour</tt> can also be substituted for a hour number.
+ # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'hour' by default.
#
# ==== Examples
@@ -485,8 +485,8 @@ def select_minute(datetime, options = {}, html_options = {})
# # Generates a select field for hours that defaults to the number given.
# select_hour(13)
#
- # # Generates a select field for hours that defaults to the minutes for the time in my_time
- # # that is named 'stride' rather than 'second'.
+ # # Generates a select field for hours that defaults to the hour for the time in my_time
+ # # that is named 'stride' rather than 'hour'.
# select_hour(my_time, :field_name => 'stride')
#
# # Generates a select field for hours with a custom prompt. Use <tt>:prompt => true</tt> for a
@@ -501,11 +501,11 @@ def select_hour(datetime, options = {}, html_options = {})
end
# Returns a select tag with options for each of the days 1 through 31 with the current day selected.
- # The <tt>date</tt> can also be substituted for a hour number.
+ # The <tt>date</tt> can also be substituted for a day number.
# Override the field name using the <tt>:field_name</tt> option, 'day' by default.
#
# ==== Examples
- # my_date = Time.today + 2.days
+ # my_date = Time.now + 2.days
#
# # Generates a select field for days that defaults to the day for the date in my_date.
# select_day(my_time)
View
45 actionpack/lib/action_view/helpers/form_helper.rb
@@ -49,7 +49,7 @@ module Helpers
# <label for="person_last_name">Last name</label>:
# <input id="person_last_name" name="person[last_name]" size="30" type="text" /><br />
#
- # <input id="person_submit" name="commit" type="submit" value="Create Person" />
+ # <input name="commit" type="submit" value="Create Person" />
# </form>
#
# As you see, the HTML reflects knowledge about the resource in several spots,
@@ -80,7 +80,7 @@ module Helpers
# <label for="person_last_name">Last name</label>:
# <input id="person_last_name" name="person[last_name]" size="30" type="text" value="Smith" /><br />
#
- # <input id="person_submit" name="commit" type="submit" value="Update Person" />
+ # <input name="commit" type="submit" value="Update Person" />
# </form>
#
# Note that the endpoint, default values, and submit button label are tailored for <tt>@person</tt>.
@@ -233,7 +233,7 @@ def convert_to_model(object)
# <% end %>
#
# If your resource has associations defined, for example, you want to add comments
- # to the post given that the routes are set correctly:
+ # to the document given that the routes are set correctly:
#
# <%= form_for([@document, @comment]) do |f| %>
# ...
@@ -259,8 +259,8 @@ def convert_to_model(object)
# :remote => true
#
# in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its
- # behaviour. The expected default behaviour is an XMLHttpRequest in the background instead of the regular
- # POST arrangement, but ultimately the behaviour is the choice of the JavaScript driver implementor.
+ # behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular
+ # POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor.
# Even though it's using JavaScript to serialize the form elements, the form submission will work just like
# a regular submission as viewed by the receiving side (all elements available in <tt>params</tt>).
#
@@ -859,7 +859,28 @@ def radio_button(object_name, method, tag_value, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
end
- # Returns a text_field of type "search".
+ # Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object
+ # assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by
+ # some browsers.
+ #
+ # ==== Examples
+ #
+ # search_field(:user, :name)
+ # # => <input id="user_name" name="user[name]" size="30" type="search" />
+ # search_field(:user, :name, :autosave => false)
+ # # => <input autosave="false" id="user_name" name="user[name]" size="30" type="search" />
+ # search_field(:user, :name, :results => 3)
+ # # => <input id="user_name" name="user[name]" results="3" size="30" type="search" />
+ # # Assume request.host returns "www.example.com"
+ # search_field(:user, :name, :autosave => true)
+ # # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" size="30" type="search" />
+ # search_field(:user, :name, :onsearch => true)
+ # # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" />
+ # search_field(:user, :name, :autosave => false, :onsearch => true)
+ # # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" />
+ # search_field(:user, :name, :autosave => true, :onsearch => true)
+ # # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" size="30" type="search" />
+ #
def search_field(object_name, method, options = {})
options = options.stringify_keys
@@ -878,17 +899,29 @@ def search_field(object_name, method, options = {})
end
# Returns a text_field of type "tel".
+ #
+ # telephone_field("user", "phone")
+ # # => <input id="user_phone" name="user[phone]" size="30" type="tel" />
+ #
def telephone_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("tel", options)
end
alias phone_field telephone_field
# Returns a text_field of type "url".
+ #
+ # url_field("user", "homepage")
+ # # => <input id="user_homepage" size="30" name="user[homepage]" type="url" />
+ #
def url_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("url", options)
end
# Returns a text_field of type "email".
+ #
+ # email_field("user", "address")
+ # # => <input id="user_address" size="30" name="user[address]" type="email" />
+ #
def email_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("email", options)
end
View
2  actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -30,7 +30,7 @@ module FormTagHelper
# (by passing <tt>false</tt>).
# * A list of parameters to feed to the URL the form will be posted to.
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
- # submit behaviour. By default this behaviour is an ajax submit.
+ # submit behavior. By default this behavior is an ajax submit.
#
# ==== Examples
# form_tag('/posts')
View
2  actionpack/lib/action_view/helpers/number_helper.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/core_ext/float/rounding'
require 'active_support/core_ext/object/blank'
View
2  actionpack/lib/action_view/helpers/translation_helper.rb
@@ -25,7 +25,7 @@ module TranslationHelper
# * a titleized version of the last key segment as a text.
#
# E.g. the value returned for a missing translation key :"blog.post.title" will be
- # <span class="translation_missing" title="translation missing: blog.post.title">Title</span>.
+ # <span class="translation_missing" title="translation missing: en.blog.post.title">Title</span>.
# This way your views will display rather reasonable strings but it will still
# be easy to spot missing translations.
#
View
8 actionpack/lib/action_view/helpers/url_helper.rb
@@ -55,8 +55,8 @@ def url_options
#
# ==== Relying on named routes
#
- # Passing a record (like an Active Record or Active Resource) instead of a Hash as the options parameter will
- # trigger the named route for that record. The lookup will happen on the name of the class. So passing a
+ # Passing a record (like an Active Record or Active Resource) instead of a Hash as the options parameter will
+ # trigger the named route for that record. The lookup will happen on the name of the class. So passing a
# Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as
# +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route).
#
@@ -113,7 +113,7 @@ def url_for(options = {})
end
# Creates a link tag of the given +name+ using a URL created by the set of +options+.
- # See the valid options in the documentation for +url_for+. It's also possible to
+ # See the valid options in the documentation for +url_for+. It's also possible to
# pass a String instead of an options hash, which generates a link tag that uses the
# value of the String as the href for the link. Using a <tt>:back</tt> Symbol instead
# of an options hash will generate a link to the referrer (a JavaScript back link
@@ -278,7 +278,7 @@ def link_to(*args, &block)
# prompt with the question specified. If the user accepts, the link is
# processed normally, otherwise no action is taken.
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
- # submit behaviour. By default this behaviour is an ajax submit.
+ # submit behavior. By default this behavior is an ajax submit.
# * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
# be placed
#
View
49 actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -12,8 +12,7 @@ module ActionView
#
# <%= render :partial => "account" %>
#
- # This would render "advertiser/_account.html.erb" and pass the instance variable @account in as a local variable
- # +account+ to the template for display.
+ # This would render "advertiser/_account.html.erb".
#
# In another template for Advertiser#buy, we could have:
#
@@ -28,32 +27,24 @@ module ActionView
#
# == The :as and :object options
#
- # By default <tt>ActionView::Partials::PartialRenderer</tt> has its object in a local variable with the same
- # name as the template. So, given
+ # By default <tt>ActionView::Partials::PartialRenderer</tt> doesn't have any local variables.
+ # The <tt>:object</tt> option can be used to pass an object to the partial. For instance:
#
- # <%= render :partial => "contract" %>
+ # <%= render :partial => "account", :object => @buyer %>
#
- # within contract we'll get <tt>@contract</tt> in the local variable +contract+, as if we had written
+ # would provide the +@buyer+ object to the partial, available under the local variable +account+ and is
+ # equivalent to:
#
- # <%= render :partial => "contract", :locals => { :contract => @contract } %>
+ # <%= render :partial => "account", :locals => { :account => @buyer } %>
#
# With the <tt>:as</tt> option we can specify a different name for said local variable. For example, if we
- # wanted it to be +agreement+ instead of +contract+ we'd do:
- #
- # <%= render :partial => "contract", :as => 'agreement' %>
- #
- # The <tt>:object</tt> option can be used to directly specify which object is rendered into the partial;
- # useful when the template's object is elsewhere, in a different ivar or in a local variable for instance.
+ # wanted it to be +user+ instead of +account+ we'd do:
#
- # Revisiting a previous example we could have written this code:
+ # <%= render :partial => "account", :object => @buyer, :as => 'user' %>
#
- # <%= render :partial => "account", :object => @buyer %>
- #
- # <% @advertisements.each do |ad| %>
- # <%= render :partial => "ad", :object => ad %>
- # <% end %>
+ # This is equivalent to
#
- # The <tt>:object</tt> and <tt>:as</tt> options can be used together.
+ # <%= render :partial => "account", :locals => { :user => @buyer } %>
#
# == Rendering a collection of partials
#
@@ -371,14 +362,28 @@ def collection_without_template
def partial_path(object = @object)
@partial_names[object.class.name] ||= begin
object = object.to_model if object.respond_to?(:to_model)
-
object.class.model_name.partial_path.dup.tap do |partial|
path = @lookup_context.prefixes.first
- partial.insert(0, "#{File.dirname(path)}/") if partial.include?(?/) && path.include?(?/)
+ merge_path_into_partial(path, partial)
end
end
end
+ def merge_path_into_partial(path, partial)
+ if path.include?(?/) && partial.include?(?/)
+ overlap = []
+ path_array = File.dirname(path).split('/')
+ partial_array = partial.split('/')[0..-3] # skip model dir & partial
+
+ path_array.each_with_index do |dir, index|
+ overlap << dir if dir == partial_array[index]
+ end
+
+ partial.gsub!(/^#{overlap.join('/')}\//,'')
+ partial.insert(0, "#{File.dirname(path)}/")
+ end
+ end
+
def retrieve_variable(path)
variable = @options[:as].try(:to_sym) || path[%r'_?(\w+)(\.\w+)*$', 1].to_sym
variable_counter = :"#{variable}_counter" if @collection
View
22 actionpack/lib/sprockets/assets.rake
@@ -1,16 +1,18 @@
namespace :assets do
+ # Ensures the RAILS_GROUPS environment variable is set
+ task :ensure_env do
+ ENV["RAILS_GROUPS"] ||= "assets"
+ end
+
desc "Compile all the assets named in config.assets.precompile"
- task :precompile do
- if ENV["RAILS_GROUPS"].to_s.empty?
- ENV["RAILS_GROUPS"] = "assets"
- Kernel.exec $0, *ARGV
- else
- Rake::Task["environment"].invoke
- Sprockets::Helpers::RailsHelper
+ task :precompile => :ensure_env do
+ Rake::Task["environment"].invoke
+ Sprockets::Helpers::RailsHelper
- assets = Rails.application.config.assets.precompile
- Rails.application.assets.precompile(*assets)
- end
+ assets = Rails.application.config.assets.precompile
+ # Always perform caching so that asset_path appends the timestamps to file references.
+ Rails.application.config.action_controller.perform_caching = true
+ Rails.application.assets.precompile(*assets)
end
desc "Remove compiled assets"
View
2  actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -72,6 +72,8 @@ def asset_path(source, default_ext = nil, body = false, protocol = nil)
def debug_assets?
params[:debug_assets] == '1' ||
params[:debug_assets] == 'true'
+ rescue NoMethodError
+ false
end
# Override to specify an alternative prefix for asset path generation.
View
4 actionpack/lib/sprockets/railtie.rb
@@ -61,10 +61,10 @@ def asset_environment(app)
env.paths.concat assets.paths
end
- env.logger = Rails.logger
+ env.logger = ::Rails.logger
if env.respond_to?(:cache) && assets.cache_store != false
- env.cache = ActiveSupport::Cache.lookup_store(assets.cache_store) || Rails.cache
+ env.cache = ActiveSupport::Cache.lookup_store(assets.cache_store) || ::Rails.cache
end
if assets.compress
View
14 actionpack/test/controller/render_test.rb
@@ -14,6 +14,14 @@ def nested_partial_with_form_builder
end
end
+module Quiz
+ class QuestionsController < ActionController::Base
+ def new
+ render :partial => Quiz::Question.new("Namespaced Partial")
+ end
+ end
+end
+
class TestController < ActionController::Base
protect_from_forgery
@@ -1251,6 +1259,12 @@ def test_nested_partial_with_form_builder
assert_template('fun/games/_form')
end
+ def test_namespaced_object_partial
+ @controller = Quiz::QuestionsController.new
+ get :new
+ assert_equal "Namespaced Partial", @response.body
+ end
+
def test_partial_collection
get :partial_collection
assert_equal "Hello: davidHello: mary", @response.body
View
6 actionpack/test/dispatch/request_test.rb
@@ -468,6 +468,12 @@ def url_for(options = {})
assert request.formats.empty?
end
+ test "formats with xhr request" do
+ request = stub_request 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
+ request.expects(:parameters).at_least_once.returns({})
+ assert_equal [Mime::JS], request.formats
+ end
+
test "ignore_accept_header" do
ActionDispatch::Request.ignore_accept_header = true
View
2  actionpack/test/template/asset_tag_helper_test.rb
@@ -443,7 +443,7 @@ def test_favicon_link_tag
def test_image_tag_windows_behaviour
old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1"
- # This simulates the behaviour of File#exist? on windows when testing a file ending in "."
+ # This simulates the behavior 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.
File.stubs(:exist?).with('template/../fixtures/public/images/rails.png.').returns(true)
View
9 actionpack/test/template/sprockets_helper_test.rb
@@ -12,7 +12,6 @@ def setup
super
@controller = BasicController.new
- @controller.stubs(:params).returns({})
@request = Class.new do
def protocol() 'http://' end
@@ -27,10 +26,8 @@ def host_with_port() 'localhost' end
@assets.paths << FIXTURES.join("sprockets/app/stylesheets")
@assets.paths << FIXTURES.join("sprockets/app/images")
- application = Object.new
+ application = Struct.new(:config, :assets).new(config, @assets)
Rails.stubs(:application).returns(application)
- application.stubs(:config).returns(config)
- application.stubs(:assets).returns(@assets)
@config = config
@config.action_controller ||= ActiveSupport::InheritableOptions.new
@config.perform_caching = true
@@ -54,7 +51,7 @@ def url_for(*args)
assert_equal "/dir/audio",
asset_path("/dir/audio")
end
-
+
test "asset_path with absolute urls" do
assert_equal "http://www.example.com/video/play",
asset_path("http://www.example.com/video/play")
@@ -74,7 +71,7 @@ def url_for(*args)
assert_match %r{http://assets-\d.example.com/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
-
+
test "With a proc asset host that returns no protocol the url should be protocol relative" do
@controller.config.asset_host = Proc.new do |asset|
"assets-999.example.com"
View
27 activemodel/README.rdoc
@@ -182,3 +182,30 @@ modules:
p.valid? # => true
{Learn more}[link:classes/ActiveModel/Validator.html]
+
+
+== Download and installation
+
+The latest version of Active Model can be installed with Rubygems:
+
+ % [sudo] gem install activemodel
+
+Source code can be downloaded as part of the Rails project on GitHub
+
+* https://github.com/rails/rails/tree/master/activemodel/
+
+
+== License
+
+Active Model is released under the MIT license.
+
+
+== Support
+
+API documentation is at
+
+* http://api.rubyonrails.org
+
+Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
+
+* https://github.com/rails/rails/issues
View
2  activemodel/lib/active_model/dirty.rb
@@ -29,7 +29,7 @@ module ActiveModel
#
# include ActiveModel::Dirty
#
- # define_attribute_methods [:name]
+ # define_attribute_methods = [:name]
#
# def name
# @name
View
10 activerecord/CHANGELOG
@@ -1,5 +1,15 @@
*Rails 3.2.0 (unreleased)*
+* If multiple parameters are sent representing a date, and some are blank, the
+resulting object is nil. In previous releases those values defaulted to 1. This
+only affects existing but blank parameters, missing ones still raise an error.
+[Akira Matsuda]
+
+* ActiveRecord::Base.establish_connection now takes a string that contains
+a URI that specifies the connection configuration. For example:
+
+ ActiveRecord::Base.establish_connection 'postgres://localhost/foo'
+
* Active Record's dynamic finder will now raise the error if you passing in less number of arguments than what you call in method signature.
So if you were doing this and expecting the second argument to be nil:
View
3  activerecord/lib/active_record.rb
@@ -41,7 +41,8 @@ module ActiveRecord
eager_autoload do
autoload :ActiveRecordError, 'active_record/errors'
autoload :ConnectionNotEstablished, 'active_record/errors'
-
+ autoload :ConnectionAdapters, 'active_record/connection_adapters/abstract_adapter'
+
autoload :Aggregations
autoload :Associations
autoload :AttributeMethods
View
2  activerecord/lib/active_record/associations/collection_association.rb
@@ -382,7 +382,7 @@ def merge_target_lists(persisted, memory)
persisted.map! do |record|
# Unfortunately we cannot simply do memory.delete(record) since on 1.8 this returns
- # record rather than memory.at(memory.index(record)). The behaviour is fixed in 1.9.
+ # record rather than memory.at(memory.index(record)). The behavior is fixed in 1.9.
mem_index = memory.index(record)
if mem_index
View
13 activerecord/lib/active_record/base.rb
@@ -1738,7 +1738,7 @@ def attributes
end
# Returns an <tt>#inspect</tt>-like string for the value of the
- # attribute +attr_name+. String attributes are elided after 50
+ # attribute +attr_name+. String attributes are truncated upto 50
# characters, and Date and Time attributes are returned in the
# <tt>:db</tt> format. Other attributes return the value of
# <tt>#inspect</tt> without modification.
@@ -2027,15 +2027,18 @@ def read_time_parameter_value(name, values_hash_from_param)
# If Date bits were not provided, error
raise "Missing Parameter" if [1,2,3].any?{|position| !values_hash_from_param.has_key?(position)}
max_position = extract_max_param_for_multiparameter_attributes(values_hash_from_param, 6)
+ # If Date bits were provided but blank, then return nil
+ return nil if (1..3).any? {|position| values_hash_from_param[position].blank?}
+
set_values = (1..max_position).collect{|position| values_hash_from_param[position] }
- # If Date bits were provided but blank, then default to 1
# If Time bits are not there, then default to 0
- [1,1,1,0,0,0].each_with_index{|v,i| set_values[i] = set_values[i].blank? ? v : set_values[i]}
+ (3..5).each {|i| set_values[i] = set_values[i].blank? ? 0 : set_values[i]}
instantiate_time_object(name, set_values)
end
def read_date_parameter_value(name, values_hash_from_param)
- set_values = (1..3).collect{|position| values_hash_from_param[position].blank? ? 1 : values_hash_from_param[position]}
+ return nil if (1..3).any? {|position| values_hash_from_param[position].blank?}
+ set_values = [values_hash_from_param[1], values_hash_from_param[2], values_hash_from_param[3]]
begin
Date.new(*set_values)
rescue ArgumentError # if Date.new raises an exception on an invalid date
@@ -2163,6 +2166,4 @@ def clear_timestamp_attributes
end
end
-# TODO: Remove this and make it work with LAZY flag
-require 'active_record/connection_adapters/abstract_adapter'
ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
View
26 activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
@@ -46,6 +46,12 @@ def connection
# "database" => "path/to/dbfile"
# )
#
+ # Or a URL:
+ #
+ # ActiveRecord::Base.establish_connection(
+ # "postgres://myuser:mypass@localhost/somedatabase"
+ # )
+ #
# The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError
# may be returned on an error.
def self.establish_connection(spec = nil)
@@ -58,6 +64,8 @@ def self.establish_connection(spec = nil)
when Symbol, String
if configuration = configurations[spec.to_s]
establish_connection(configuration)
+ elsif spec.is_a?(String) && hash = connection_url_to_hash(spec)
+ establish_connection(hash)
else
raise AdapterNotSpecified, "#{spec} database is not configured"
end
@@ -81,6 +89,24 @@ def self.establish_connection(spec = nil)
end
end
+ def self.connection_url_to_hash(url) # :nodoc:
+ config = URI.parse url
+ adapter = config.scheme
+ adapter = "postgresql" if adapter == "postgres"
+ spec = { :adapter => adapter,
+ :username => config.user,
+ :password => config.password,
+ :port => config.port,
+ :database => config.path.sub(%r{^/},""),
+ :host => config.host }
+ spec.reject!{ |_,value| !value }
+ if config.query
+ options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
+ spec.merge!(options)
+ end
+ spec
+ end
+
class << self
# Returns the connection currently associated with the class. This can
# also be used to "borrow" the connection to do database work unrelated
View
5 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -157,6 +157,11 @@ def quoted_date(value) #:nodoc:
end
end
+ def type_cast(value, column) # :nodoc:
+ return super unless BigDecimal === value
+
+ value.to_f
+ end
# DATABASE STATEMENTS ======================================
View
2  activerecord/lib/active_record/migration.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/module/delegation"
+require "active_support/core_ext/class/attribute_accessors"
require "active_support/core_ext/array/wrap"
module ActiveRecord
View
2  activerecord/lib/active_record/nested_attributes.rb
@@ -383,7 +383,7 @@ def assign_nested_attributes_for_collection_association(association_name, attrib
attributes_collection = if keys.include?('id') || keys.include?(:id)
Array.wrap(attributes_collection)
else
- attributes_collection.sort_by { |i, _| i.to_i }.map { |_, attributes| attributes }
+ attributes_collection.values
end
end
View
3  activerecord/lib/active_record/railties/databases.rake
@@ -115,7 +115,8 @@ db_namespace = namespace :db do
end
end
else
- $stderr.puts "#{config['database']} already exists"
+ # Bug with 1.9.2 Calling return within begin still executes else
+ $stderr.puts "#{config['database']} already exists" unless config['adapter'] =~ /sqlite/
end
end
View
2  activerecord/lib/active_record/relation/finder_methods.rb
@@ -243,7 +243,7 @@ def apply_join_dependency(relation, join_dependency)
end
def construct_limited_ids_condition(relation)
- orders = relation.order_values
+ orders = relation.order_values.map { |val| val.presence }.compact
values = @klass.connection.distinct("#{@klass.connection.quote_table_name table_name}.#{primary_key}", orders)
relation = relation.dup
View
1  activerecord/lib/active_record/relation/query_methods.rb
@@ -311,6 +311,7 @@ def reverse_sql_order(order_query)
o.reverse
when String, Symbol
o.to_s.split(',').collect do |s|
+ s.strip!
s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
end
else
View
6 activerecord/test/cases/adapter_test.rb
@@ -81,12 +81,6 @@ def test_not_specifying_database_name_for_cross_database_selects
end
end
- if current_adapter?(:PostgreSQLAdapter)
- def test_encoding
- assert_not_nil @connection.encoding
- end
- end
-
def test_table_alias
def @connection.test_table_alias_length() 10; end
class << @connection
View
10 activerecord/test/cases/adapters/mysql/connection_test.rb
@@ -13,6 +13,16 @@ def test_mysql_reconnect_attribute_after_connection_with_reconnect_true
end
end
+ def test_connect_with_url
+ run_without_connection do |orig|
+ ar_config = ARTest.connection_config['arunit']
+ url = "mysql://#{ar_config["username"]}@localhost/#{ar_config["database"]}"
+ klass = Class.new(ActiveRecord::Base)
+ klass.establish_connection(url)
+ assert_equal ar_config['database'], klass.connection.current_database
+ end
+ end
+
def test_mysql_reconnect_attribute_after_connection_with_reconnect_false
run_without_connection do |orig_connection|
ActiveRecord::Base.establish_connection(orig_connection.merge({:reconnect => false}))
View
14 activerecord/test/cases/adapters/postgresql/connection_test.rb
@@ -0,0 +1,14 @@
+require "cases/helper"
+
+module ActiveRecord
+ class PostgresqlConnectionTest < ActiveRecord::TestCase
+ def setup
+ super
+ @connection = ActiveRecord::Base.connection
+ end
+
+ def test_encoding
+ assert_not_nil @connection.encoding
+ end
+ end
+end
View
2  activerecord/test/cases/adapters/sqlite3/quoting_test.rb
@@ -67,7 +67,7 @@ def test_type_cast_string
def test_type_cast_bigdecimal
bd = BigDecimal.new '10.0'
- assert_equal bd.to_s('F'), @conn.type_cast(bd, nil)
+ assert_equal bd.to_f, @conn.type_cast(bd, nil)
end
def test_type_cast_unknown
View
12 activerecord/test/cases/associations/eager_test.rb
@@ -1048,4 +1048,16 @@ def test_joins_with_includes_should_preload_via_joins
assert_not_equal 0, post.comments.to_a.count
end
end
+
+ def test_join_eager_with_empty_order_should_generate_valid_sql
+ assert_nothing_raised(ActiveRecord::StatementInvalid) do
+ Post.includes(:comments).order("").where(:comments => {:body => "Thank you for the welcome"}).first
+ end
+ end
+
+ def test_join_eager_with_nil_order_should_generate_valid_sql
+ assert_nothing_raised(ActiveRecord::StatementInvalid) do
+ Post.includes(:comments).order(nil).where(:comments => {:body => "Thank you for the welcome"}).first
+ end
+ end
end
View
44 activerecord/test/cases/base_test.rb
@@ -540,7 +540,7 @@ def test_multiparameter_attributes_on_date_with_empty_year
topic.attributes = attributes
# note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
- assert_date_from_db Date.new(1, 6, 24), topic.last_read.to_date
+ assert_nil topic.last_read
end
def test_multiparameter_attributes_on_date_with_empty_month
@@ -549,7 +549,7 @@ def test_multiparameter_attributes_on_date_with_empty_month
topic.attributes = attributes
# note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
- assert_date_from_db Date.new(2004, 1, 24), topic.last_read.to_date
+ assert_nil topic.last_read
end
def test_multiparameter_attributes_on_date_with_empty_day
@@ -558,7 +558,7 @@ def test_multiparameter_attributes_on_date_with_empty_day
topic.attributes = attributes
# note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
- assert_date_from_db Date.new(2004, 6, 1), topic.last_read.to_date
+ assert_nil topic.last_read
end
def test_multiparameter_attributes_on_date_with_empty_day_and_year
@@ -567,7 +567,7 @@ def test_multiparameter_attributes_on_date_with_empty_day_and_year
topic.attributes = attributes
# note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
- assert_date_from_db Date.new(1, 6, 1), topic.last_read.to_date
+ assert_nil topic.last_read
end
def test_multiparameter_attributes_on_date_with_empty_day_and_month
@@ -576,7 +576,7 @@ def test_multiparameter_attributes_on_date_with_empty_day_and_month
topic.attributes = attributes
# note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
- assert_date_from_db Date.new(2004, 1, 1), topic.last_read.to_date
+ assert_nil topic.last_read
end
def test_multiparameter_attributes_on_date_with_empty_year_and_month
@@ -585,7 +585,7 @@ def test_multiparameter_attributes_on_date_with_empty_year_and_month
topic.attributes = attributes
# note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
- assert_date_from_db Date.new(1, 1, 24), topic.last_read.to_date
+ assert_nil topic.last_read
end
def test_multiparameter_attributes_on_date_with_all_empty
@@ -678,12 +678,7 @@ def test_multiparameter_attributes_on_time_will_ignore_hour_if_blank
}
topic = Topic.find(1)
topic.attributes = attributes
- assert_equal 1, topic.written_on.year
- assert_equal 1, topic.written_on.month
- assert_equal 1, topic.written_on.day
- assert_equal 0, topic.written_on.hour
- assert_equal 12, topic.written_on.min
- assert_equal 2, topic.written_on.sec
+ assert_nil topic.written_on
end
def test_multiparameter_attributes_on_time_will_ignore_date_if_empty
@@ -693,12 +688,7 @@ def test_multiparameter_attributes_on_time_will_ignore_date_if_empty
}
topic = Topic.find(1)
topic.attributes = attributes
- assert_equal 1, topic.written_on.year
- assert_equal 1, topic.written_on.month
- assert_equal 1, topic.written_on.day
- assert_equal 16, topic.written_on.hour
- assert_equal 24, topic.written_on.min
- assert_equal 0, topic.written_on.sec
+ assert_nil topic.written_on
end
def test_multiparameter_attributes_on_time_with_seconds_will_ignore_date_if_empty
attributes = {
@@ -707,12 +697,7 @@ def test_multiparameter_attributes_on_time_with_seconds_will_ignore_date_if_empt
}
topic = Topic.find(1)
topic.attributes = attributes
- assert_equal 1, topic.written_on.year
- assert_equal 1, topic.written_on.month
- assert_equal 1, topic.written_on.day
- assert_equal 16, topic.written_on.hour
- assert_equal 12, topic.written_on.min
- assert_equal 02, topic.written_on.sec
+ assert_nil topic.written_on
end
def test_multiparameter_attributes_on_time_with_utc
@@ -1113,6 +1098,17 @@ class NumericData < ActiveRecord::Base
self.table_name = 'numeric_data'
end
+ def test_big_decimal_conditions
+ m = NumericData.new(
+ :bank_balance => 1586.43,
+ :big_bank_balance => BigDecimal("1000234000567.95"),
+ :world_population => 6000000000,
+ :my_house_population => 3
+ )
+ assert m.save
+ assert_equal 0, NumericData.where("bank_balance > ?", 2000.0).count
+ end
+
def test_numeric_fields
m = NumericData.new(
:bank_balance => 1586.43,
View
34 activerecord/test/cases/connection_management_test.rb
@@ -25,6 +25,40 @@ def setup
assert ActiveRecord::Base.connection_handler.active_connections?
end
+ class FakeBase < ActiveRecord::Base
+ def self.establish_connection spec
+ String === spec ? super : spec
+ end
+ end
+
+ def test_url_host_no_db
+ spec = FakeBase.establish_connection 'postgres://foo?encoding=utf8'
+ assert_equal({
+ :adapter => "postgresql",
+ :database => "",
+ :host => "foo",
+ :encoding => "utf8" }, spec)
+ end
+
+ def test_url_host_db
+ spec = FakeBase.establish_connection 'postgres://foo/bar?encoding=utf8'
+ assert_equal({
+ :adapter => "postgresql",
+ :database => "bar",
+ :host => "foo",
+ :encoding => "utf8" }, spec)
+ end
+
+ def test_url_port
+ spec = FakeBase.establish_connection 'postgres://foo:123?encoding=utf8'
+ assert_equal({
+ :adapter => "postgresql",
+ :database => "",
+ :port => 123,
+ :host => "foo",
+ :encoding => "utf8" }, spec)
+ end
+
def test_app_delegation
manager = ConnectionManagement.new(@app)
View
4 activerecord/test/cases/identity_map_test.rb
@@ -164,7 +164,7 @@ def test_inherited_with_type_attribute
end
##############################################################################
- # Tests checking dirty attribute behaviour with IM #
+ # Tests checking dirty attribute behavior with IM #
##############################################################################
def test_loading_new_instance_should_not_update_dirty_attributes
@@ -238,7 +238,7 @@ def test_im_with_polymorphic_has_many_going_through_join_model_with_custom_selec
end
##############################################################################
- # Tests checking Identity Map behaviour with preloaded associations, joins, #
+ # Tests checking Identity Map behavior with preloaded associations, joins, #
# includes etc. #
##############################################################################
View
4 activerecord/test/cases/invalid_date_test.rb
@@ -24,9 +24,9 @@ def test_assign_valid_dates
topic = Topic.new({"last_read(1i)" => date_src[0].to_s, "last_read(2i)" => date_src[1].to_s, "last_read(3i)" => date_src[2].to_s})
# Oracle DATE columns are datetime columns and Oracle adapter returns Time value
if current_adapter?(:OracleAdapter)
- assert_equal(topic.last_read.to_date, Time.local(*date_src).to_date, "The date should be modified according to the behaviour of the Time object")
+ assert_equal(topic.last_read.to_date, Time.local(*date_src).to_date, "The date should be modified according to the behavior of the Time object")
else
- assert_equal(topic.last_read, Time.local(*date_src).to_date, "The date should be modified according to the behaviour of the Time object")
+ assert_equal(topic.last_read, Time.local(*date_src).to_date, "The date should be modified according to the behavior of the Time object")
end
end
end
View
5 activerecord/test/cases/nested_attributes_test.rb
@@ -755,6 +755,11 @@ def test_validate_presence_of_parent_fails_without_inverse_of
Interest.reflect_on_association(:man).options[:inverse_of] = :interests
end
+ def test_can_use_symbols_as_object_identifier
+ @pirate.attributes = { :parrots_attributes => { :foo => { :name => 'Lovely Day' }, :bar => { :name => 'Blown Away' } } }
+ assert_nothing_raised(NoMethodError) { @pirate.save! }
+ end
+
private
def association_setter
View
4 activerecord/test/cases/relations_test.rb
@@ -961,4 +961,8 @@ def test_eager_loading_with_conditions_on_joins
assert scope.eager_loading?
end
+
+ def test_ordering_with_extra_spaces
+ assert_equal authors(:david), Author.order('organization_id ASC , owned_essay_id DESC').last
+ end
end
View
2  activeresource/lib/active_resource/base.rb
@@ -395,7 +395,7 @@ def site
# Subclass.site.user = 'david'
# Parent.site # => 'http://david@test.com'
#
- # Without superclass_delegating_reader (expected behaviour)
+ # Without superclass_delegating_reader (expected behavior)
#
# Parent.site = 'http://anonymous@test.com'
# Subclass.site # => 'http://anonymous@test.com'
View
2  activeresource/lib/active_resource/http_mock.rb
@@ -149,7 +149,7 @@ def responses
# Note, by default, every time you call +respond_to+, any previous request and response pairs stored
# in HttpMock will be deleted giving you a clean slate to work on.
#
- # If you want to override this behaviour, pass in +false+ as the last argument to +respond_to+
+ # If you want to override this behavior, pass in +false+ as the last argument to +respond_to+
#
# === Example
#
View
3  activesupport/CHANGELOG
@@ -1,5 +1,8 @@
*Rails 3.2.0 (unreleased)*
+* The definition of blank string for Ruby 1.9 has been extended to Unicode whitespace.
+Also, in 1.8 the ideographic space U+3000 is considered to be whitespace. [Akira Matsuda, Damien Mathieu]
+
* The inflector understands acronyms. [dlee]
* Deprecated ActiveSupport::Memoizable in favor of Ruby memoization pattern [José Valim]
View
2  activesupport/lib/active_support/cache/file_store.rb
@@ -16,7 +16,7 @@ class FileStore < Store
def initialize(cache_path, options = nil)
super(options)
- @cache_path = cache_path
+ @cache_path = cache_path.to_s
extend Strategy::LocalCache
end
View
8 activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -110,12 +110,6 @@ def #{name}?
private
def singleton_class?
- # in case somebody is crazy enough to overwrite allocate
- allocate = Class.instance_method(:allocate)
- # object.class always points to a real (non-singleton) class
- allocate.bind(self).call.class != self
- rescue TypeError
- # MRI/YARV/JRuby all disallow creating new instances of a singleton class
- true
+ !name || '' == name
end
end
View
22 activesupport/lib/active_support/core_ext/enumerable.rb
@@ -20,6 +20,7 @@ module Enumerable
# "2006-02-24 -> Transcript, Transcript"
# "2006-02-23 -> Transcript"
def group_by
+ return to_enum :group_by unless block_given?
assoc = ActiveSupport::OrderedHash.new
each do |element|
@@ -75,9 +76,10 @@ def sum(identity = 0, &block)
#
# (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
#
- def each_with_object(memo, &block)
+ def each_with_object(memo)
+ return to_enum :each_with_object, memo unless block_given?
each do |element|
- block.call(element, memo)
+ yield element, memo
end
memo
end unless [].respond_to?(:each_with_object)
@@ -90,14 +92,22 @@ def each_with_object(memo, &block)
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
#
def index_by
+ return to_enum :index_by unless block_given?
Hash[map { |elem| [yield(elem), elem] }]
end
- # Returns true if the collection has more than 1 element. Functionally equivalent to collection.size > 1.
+ # Returns true if the enumerable has more than 1 element. Functionally equivalent to enum.to_a.size > 1.
# Can be called with a block too, much like any?, so people.many? { |p| p.age > 26 } returns true if more than 1 person is over 26.
- def many?(&block)
- size = block_given? ? count(&block) : self.size
- size > 1
+ def many?
+ cnt = 0
+ if block_given?
+ any? do |element|
+ cnt += 1 if yield element
+ cnt > 1
+ end
+ else
+ any?{ (cnt += 1) > 1 }
+ end
end
# The negative of the Enumerable#include?. Returns true if the collection does not include the object.
View
8 activesupport/lib/active_support/core_ext/object/blank.rb
@@ -1,4 +1,5 @@
# encoding: utf-8
+require 'active_support/core_ext/string/encoding'
class Object
# An object is blank if it's false, empty, or a whitespace string.
@@ -99,7 +100,12 @@ class String
# " something here ".blank? # => false
#
def blank?
- self !~ NON_WHITESPACE_REGEXP
+ # 1.8 does not takes [:space:] properly
+ if encoding_aware?
+ self !~ /[^[:space:]]/
+ else
+ self !~ NON_WHITESPACE_REGEXP
+ end
end
end
View
1  activesupport/lib/active_support/core_ext/string/conversions.rb
@@ -1,3 +1,4 @@
+# encoding: utf-8
require 'date'
require 'active_support/core_ext/time/publicize_conversion_methods'
require 'active_support/core_ext/time/calculations'
View
2  activesupport/lib/active_support/core_ext/string/multibyte.rb
@@ -35,7 +35,7 @@ class String
# object. Interoperability problems can be resolved easily with a +to_s+ call.
#
# For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
- # information about how to change the default Multibyte behaviour see ActiveSupport::Multibyte.
+ # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
def mb_chars
if ActiveSupport::Multibyte.proxy_class.consumes?(self)
ActiveSupport::Multibyte.proxy_class.new(self)
View
4 activesupport/lib/active_support/deprecation/behaviors.rb
@@ -7,12 +7,12 @@ class << self
# Whether to print a backtrace along with the warning.
attr_accessor :debug
- # Returns the set behaviour or if one isn't set, defaults to +:stderr+
+ # Returns the set behavior or if one isn't set, defaults to +:stderr+
def behavior
@behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
end
- # Sets the behaviour to the specified value. Can be a single value or an array.
+ # Sets the behavior to the specified value. Can be a single value or an array.
#
# Examples
#
View
6 activesupport/lib/active_support/inflector/methods.rb
@@ -118,8 +118,10 @@ def humanize(lower_case_and_underscored_word)
# +titleize+ is also aliased as as +titlecase+.
#
# Examples:
- # "man from the boondocks".titleize # => "Man From The Boondocks"
- # "x-men: the last stand".titleize # => "X Men: The Last Stand"
+ # "man from the boondocks".titleize # => "Man From The Boondocks"
+ # "x-men: the last stand".titleize # => "X Men: The Last Stand"
+ # "TheManWithoutAPast".titleize # => "The Man Without A Past"
+ # "raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
def titleize(word)
humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
end
View
3  activesupport/lib/active_support/multibyte/chars.rb
@@ -331,8 +331,7 @@ def slice(*args)
# when the storage for a string is limited for some reason.
#
# Example:
- # s = 'こんにちは'
- # s.mb_chars.limit(7) # => "こに"
+ # 'こんにちは'.mb_chars.limit(7).to_s # => "こん"
def limit(limit)
slice(0...translate_offset(limit))
end
View
1  activesupport/lib/active_support/multibyte/unicode.rb
@@ -1,3 +1,4 @@
+# encoding: utf-8
module ActiveSupport
module Multibyte
module Unicode
View
2  activesupport/lib/active_support/ordered_hash.rb
@@ -6,7 +6,7 @@
require 'yaml'
YAML.add_builtin_type("omap") do |type, val|
- ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
+ ActiveSupport::OrderedHash[val.map{ |v| v.to_a.first }]
end
module ActiveSupport
View
7 activesupport/test/caching_test.rb
@@ -521,6 +521,7 @@ def setup
Dir.mkdir(cache_dir) unless File.exist?(cache_dir)
@cache = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60)
@peek = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60)
+ @cache_with_pathname = ActiveSupport::Cache.lookup_store(:file_store, Pathname.new(cache_dir), :expires_in => 60)
end
def teardown
@@ -540,6 +541,12 @@ def test_key_transformation
key = @cache.send(:key_file_path, "views/index?id=1")
assert_equal "views/index?id=1", @cache.send(:file_path_key, key)
end
+
+ def test_key_transformation_with_pathname
+ FileUtils.touch(File.join(cache_dir, "foo"))
+ key = @cache_with_pathname.send(:key_file_path, "views/index?id=1")
+ assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key)
+ end
end
class MemoryStoreTest < ActiveSupport::TestCase
View
19 activesupport/test/core_ext/duplicable_test.rb
@@ -4,22 +4,27 @@
require 'active_support/core_ext/numeric/time'
class DuplicableTest < Test::Unit::TestCase
- NO = [nil, false, true, :symbol, 1, 2.3, BigDecimal.new('4.56'), Class.new, Module.new, 5.seconds]
+ RAISE_DUP = [nil, false, true, :symbol, 1, 2.3, BigDecimal.new('4.56'), 5.seconds]
YES = ['1', Object.new, /foo/, [], {}, Time.now]
+ NO = [Class.new, Module.new]
def test_duplicable
- NO.each do |v|
+ (RAISE_DUP + NO).each do |v|
assert !v.duplicable?
- begin
- v.dup
- fail
- rescue Exception
- end
end
YES.each do |v|
assert v.duplicable?
+ end
+
+ (YES + NO).each do |v|
assert_nothing_raised { v.dup }
end
+
+ RAISE_DUP.each do |v|
+ assert_raises(TypeError) do
+ v.dup
+ end
+ end
end
end
View
84 activesupport/test/core_ext/enumerable_test.rb
@@ -8,6 +8,19 @@ def +(p) self.class.new(price + p.price) end
end
class EnumerableTests < Test::Unit::TestCase
+ Enumerator = [].each.class
+
+ class GenericEnumerable
+ include Enumerable
+ def initialize(values = [1, 2, 3])
+ @values = values
+ end
+
+ def each
+ @values.each{|v| yield v}
+ end
+ end
+
def test_group_by
names = %w(marcel sam david jeremy)
klass = Struct.new(:name)
@@ -17,7 +30,8 @@ def test_group_by
people << p
end
- grouped = objects.group_by { |object| object.name }
+ enum = GenericEnumerable.new(objects)
+ grouped = enum.group_by { |object| object.name }
grouped.each do |name, group|
assert group.all? { |person| person.name == name }
@@ -25,20 +39,24 @@ def test_group_by
assert_equal objects.uniq.map(&:name), grouped.keys
assert({}.merge(grouped), "Could not convert ActiveSupport::OrderedHash into Hash")
+ assert_equal Enumerator, enum.group_by.class
+ assert_equal grouped, enum.group_by.each(&:name)
end
def test_sums
- assert_equal 30, [5, 15, 10].sum
- assert_equal 30, [5, 15, 10].sum { |i| i }
+ enum = GenericEnumerable.new([5, 15, 10])
+ assert_equal 30, enum.sum
+ assert_equal 60, enum.sum { |i| i * 2}
- assert_equal 'abc', %w(a b c).sum
- assert_equal 'abc', %w(a b c).sum { |i| i }
+ enum = GenericEnumerable.new(%w(a b c))
+ assert_equal 'abc', enum.sum
+ assert_equal 'aabbcc', enum.sum { |i| i * 2 }
- payments = [ Payment.new(5), Payment.new(15), Payment.new(10) ]
+ payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10) ])
assert_equal 30, payments.sum(&:price)
assert_equal 60, payments.sum { |p| p.price * 2 }
- payments = [ SummablePayment.new(5), SummablePayment.new(15) ]
+ payments = GenericEnumerable.new([ SummablePayment.new(5), SummablePayment.new(15) ])
assert_equal SummablePayment.new(20), payments.sum
assert_equal SummablePayment.new(20), payments.sum { |p| p }
end
@@ -46,21 +64,21 @@ def test_sums
def test_nil_sums
expected_raise = TypeError
- assert_raise(expected_raise) { [5, 15, nil].sum }
+ assert_raise(expected_raise) { GenericEnumerable.new([5, 15, nil]).sum }
- payments = [ Payment.new(5), Payment.new(15), Payment.new(10), Payment.new(nil) ]
+ payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10), Payment.new(nil) ])
assert_raise(expected_raise) { payments.sum(&:price) }
assert_equal 60, payments.sum { |p| p.price.to_i * 2 }
end
def test_empty_sums
- assert_equal 0, [].sum
- assert_equal 0, [].sum { |i| i }
- assert_equal Payment.new(0), [].sum(Payment.new(0))
+ assert_equal 0, GenericEnumerable.new([]).sum
+ assert_equal 0, GenericEnumerable.new([]).sum { |i| i + 10 }
+ assert_equal Payment.new(0), GenericEnumerable.new([]).sum(Payment.new(0))
end
- def test_enumerable_sums
+ def test_range_sums
assert_equal 20, (1..4).sum { |i| i * 2 }
assert_equal 10, (1..4).sum
assert_equal 10, (1..4.5).sum
@@ -69,29 +87,43 @@ def test_enumerable_sums
end
def test_each_with_object
- result = %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
+ enum = GenericEnumerable.new(%w(foo bar))
+ result = enum.each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
assert_equal({'foo' => 'FOO', 'bar' => 'BAR'}, result)
+ assert_equal Enumerator, enum.each_with_object({}).class
+ result2 = enum.each_with_object({}).each{|str, hsh| hsh[str] = str.upcase}
+ assert_equal result, result2
end
def test_index_by
- payments = [ Payment.new(5), Payment.new(15), Payment.new(10) ]
- assert_equal({ 5 => payments[0], 15 => payments[1], 10 => payments[2] },
+ payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10) ])
+ assert_equal({ 5 => Payment.new(5), 15 => Payment.new(15), 10 => Payment.new(10) },
payments.index_by { |p| p.price })
+ assert_equal Enumerator, payments.index_by.class
+ assert_equal({ 5 => Payment.new(5), 15 => Payment.new(15), 10 => Payment.new(10) },
+ payments.index_by.each { |p| p.price })
end
def test_many
- assert ![].many?
- assert ![ 1 ].many?
- assert [ 1, 2 ].many?
-
- assert ![].many? {|x| x > 1 }
- assert ![ 2 ].many? {|x| x > 1 }
- assert ![ 1, 2 ].many? {|x| x > 1 }
- assert [ 1, 2, 2 ].many? {|x| x > 1 }
+ assert_equal false, GenericEnumerable.new([] ).many?
+ assert_equal false, GenericEnumerable.new([ 1 ] ).many?
+ assert_equal true, GenericEnumerable.new([ 1, 2 ] ).many?
+
+ assert_equal false, GenericEnumerable.new([] ).many? {|x| x > 1 }
+ assert_equal false, GenericEnumerable.new([ 2 ] ).many? {|x| x > 1 }
+ assert_equal false, GenericEnumerable.new([ 1, 2 ] ).many? {|x| x > 1 }
+ assert_equal true, GenericEnumerable.new([ 1, 2, 2 ]).many? {|x| x > 1 }
+ end
+
+ def test_many_iterates_only_on_what_is_needed
+ infinity = 1.0/0.0
+ very_long_enum = 0..infinity
+ assert_equal true, very_long_enum.many?
+ assert_equal true, very_long_enum.many?{|x| x > 100}
end
def test_exclude?
- assert [ 1 ].exclude?(2)
- assert ![ 1 ].exclude?(1)
+ assert_equal true, GenericEnumerable.new([ 1 ]).exclude?(2)
+ assert_equal false, GenericEnumerable.new([ 1 ]).exclude?(1)
end
end
View
2  activesupport/test/core_ext/string_ext_test.rb
@@ -158,7 +158,7 @@ def test_string_to_time
assert_equal Time.local(2005, 2, 27, 23, 50, 19, 275038), "2005-02-27T23:50:19.275038".to_time(:local)
assert_equal DateTime.civil(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time
assert_equal Time.local_time(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time(:local)
- assert_equal Time.utc(2039, 2, 27, 23, 50), "2039-02-27 22:50 -0100".to_time
+ assert_equal Time.utc(2011, 2, 27, 23, 50), "2011-02-27 22:50 -0100".to_time
assert_nil "".to_time
end
View
2  activesupport/test/json/decoding_test.rb
@@ -1,4 +1,4 @@
-# encoding: UTF-8
+# encoding: utf-8
require 'abstract_unit'
require 'active_support/json'
require 'active_support/time'
View
142 ci/travis.rb
@@ -0,0 +1,142 @@
+#!/usr/bin/env ruby
+require 'fileutils'
+include FileUtils
+
+commands = [
+ 'mysql -e "create database activerecord_unittest;"',
+ 'mysql -e "create database activerecord_unittest2;"',
+ 'psql -c "create database activerecord_unittest;" -U postgres',
+ 'psql -c "create database activerecord_unittest2;" -U postgres'
+]
+
+commands.each do |command|
+ system("#{command} > /dev/null 2>&1")
+end
+
+class Build
+ MAP = {
+ 'railties' => 'railties',
+ 'ap' => 'actionpack',
+ 'am' => 'actionmailer',
+ 'amo' => 'activemodel',
+ 'ares' => 'activeresource',
+ 'as' => 'activesupport',
+ 'ar' => 'activerecord'
+ }
+
+ attr_reader :component, :options
+
+ def initialize(component, options = {})
+ @component = component
+ @options = options
+ end
+
+ def run!(options = {})
+ self.options.update(options)
+ Dir.chdir(dir) do
+ announce(heading)
+ ENV['IM'] = identity_map?.inspect
+ rake(*tasks)
+ end
+ end
+
+ def announce(heading)
+ puts "\n\e[1;33m[Travis CI] #{heading}\e[m\n"
+ end
+
+ def heading
+ heading = [gem]
+ heading << "with #{adapter} IM #{identity_map? ? 'enabled' : 'disabled'}" if activerecord?
+ heading << "in isolation" if isolated?
+ heading.join(' ')
+ end
+
+ def tasks
+ if activerecord?
+ ['mysql:rebuild_databases', "#{adapter}:#{'isolated_' if isolated?}test"]
+ else
+ ["test#{':isolated' if isolated?}"]
+ end
+ end
+
+ def key
+ key = [gem]
+ key << adapter if activerecord?