diff options
105 files changed, 546 insertions, 1506 deletions
@@ -47,7 +47,7 @@ instance_eval File.read '.Gemfile' if File.exists? '.Gemfile' platforms :mri do group :test do - gem 'ruby-prof' if RUBY_VERSION < '1.9.3' + gem 'ruby-prof' end end diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 7ecc35b7c7..b506f8804c 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.version = version s.summary = 'Email composition, delivery, and receiving framework (part of Rails).' s.description = 'Email on Rails. Compose, deliver, receive, and test emails using the familiar controller/view pattern. First-class support for multipart email and attachments.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 8f2c567e3e..71c156f1a2 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -668,7 +668,7 @@ module ActionMailer #:nodoc: end end - # Translates the +subject+ using Rails I18n class under <tt>[:actionmailer, mailer_scope, action_name]</tt> scope. + # Translates the +subject+ using Rails I18n class under <tt>[mailer_scope, action_name]</tt> scope. # If it does not find a translation for the +subject+ under the specified scope it will default to a # humanized version of the <tt>action_name</tt>. def default_i18n_subject #:nodoc: diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index fe5bed70a9..e369277e5a 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.version = version s.summary = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).' s.description = 'Web apps on Rails. Simple, battle-tested conventions for building and testing MVC web applications. Works with any Rack-compatible server.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index bee446c8a5..d5a0b80fd5 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -33,7 +33,7 @@ module ActionDispatch end def internal_request_id - SecureRandom.hex(16) + SecureRandom.uuid end end end diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index 96c3eec337..56f15604a6 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -1,4 +1,3 @@ -require 'action_view/helpers/form_helper' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/enumerable' require 'active_support/core_ext/object/blank' @@ -47,9 +46,5 @@ module ActionView options['type'] != 'hidden' end end - - class InstanceTag - include ActiveModelInstanceTag - end end end diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index dd2b59cb0a..2806348337 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -422,7 +422,7 @@ module ActionView end # Returns a select tag with options for each of the seconds 0 through 59 with the current second selected. - # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer. + # 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 @@ -448,7 +448,7 @@ module ActionView # 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>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer. + # 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 @@ -473,7 +473,7 @@ module ActionView end # Returns a select tag with options for each of the hours 0 through 23 with the current hour selected. - # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer. + # 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 @@ -868,7 +868,7 @@ module ActionView tag_options = { :value => value } tag_options[:selected] = "selected" if selected == i text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value - text = options[:ampm] ? AMPM_TRANSLATION[i] : text + text = options[:ampm] ? AMPM_TRANSLATION[i] : text select_options << content_tag(:option, text, tag_options) end (select_options.join("\n") + "\n").html_safe @@ -974,7 +974,7 @@ module ActionView end end - class InstanceTag #:nodoc: + module DateHelperInstanceTag def to_date_select_tag(options = {}, html_options = {}) datetime_selector(options, html_options).select_date.html_safe end @@ -1030,6 +1030,10 @@ module ActionView end end + class InstanceTag #:nodoc: + include DateHelperInstanceTag + end + class FormBuilder def date_select(method, options = {}, html_options = {}) @template.date_select(@object_name, method, objectify_options(options), html_options) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ccb2275329..ffb5a729ed 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -2,6 +2,7 @@ require 'cgi' require 'action_view/helpers/date_helper' require 'action_view/helpers/tag_helper' require 'action_view/helpers/form_tag_helper' +require 'action_view/helpers/active_model_helper' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/module/method_names' @@ -963,7 +964,7 @@ module ActionView end class InstanceTag - include Helpers::TagHelper, Helpers::FormTagHelper + include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper attr_reader :object, :method_name, :object_name diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index f895cad058..3ee0d8ebc5 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -584,7 +584,7 @@ module ActionView # [nil, []] # { nil => [] } # - if !choices.empty? && Array === choices.first.last + if !choices.empty? && choices.first.respond_to?(:last) && Array === choices.first.last option_tags = grouped_options_for_select(choices, :selected => selected_value, :disabled => options[:disabled]) else option_tags = options_for_select(choices, :selected => selected_value, :disabled => options[:disabled]) diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index b37e837a23..1c0fdb8ff9 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -1,7 +1,6 @@ # 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' require 'active_support/core_ext/string/output_safety' diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index f855ea257c..7fa86866a7 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -1,6 +1,5 @@ require "pathname" require "active_support/core_ext/class" -require "active_support/core_ext/io" require "action_view/template" module ActionView diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index b64e275363..0e75a23cfd 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -665,13 +665,8 @@ XML FILES_DIR = File.dirname(__FILE__) + '/../fixtures/multipart' - if RUBY_VERSION < '1.9' - READ_BINARY = 'rb' - READ_PLAIN = 'r' - else - READ_BINARY = 'rb:binary' - READ_PLAIN = 'r:binary' - end + READ_BINARY = 'rb:binary' + READ_PLAIN = 'r:binary' def test_test_uploaded_file filename = 'mona_lisa.jpg' diff --git a/actionpack/test/dispatch/request_id_test.rb b/actionpack/test/dispatch/request_id_test.rb index b6e8b6c3ad..e2a38af233 100644 --- a/actionpack/test/dispatch/request_id_test.rb +++ b/actionpack/test/dispatch/request_id_test.rb @@ -14,7 +14,7 @@ class RequestIdTest < ActiveSupport::TestCase end test "generating a request id when none is supplied" do - assert_match(/\w+/, stub_request.uuid) + assert_match /\w+-\w+-\w+-\w+-\w+/, stub_request.uuid end private diff --git a/actionpack/test/lib/testing_sandbox.rb b/actionpack/test/lib/testing_sandbox.rb deleted file mode 100644 index c36585104f..0000000000 --- a/actionpack/test/lib/testing_sandbox.rb +++ /dev/null @@ -1,15 +0,0 @@ -module TestingSandbox - # Temporarily replaces KCODE for the block - def with_kcode(kcode) - if RUBY_VERSION < '1.9' - old_kcode, $KCODE = $KCODE, kcode - begin - yield - ensure - $KCODE = old_kcode - end - else - yield - end - end -end diff --git a/actionpack/test/template/active_model_helper_test.rb b/actionpack/test/template/active_model_helper_test.rb index 8530a72a82..52be0f1762 100644 --- a/actionpack/test/template/active_model_helper_test.rb +++ b/actionpack/test/template/active_model_helper_test.rb @@ -4,7 +4,7 @@ class ActiveModelHelperTest < ActionView::TestCase tests ActionView::Helpers::ActiveModelHelper silence_warnings do - class Post < Struct.new(:author_name, :body) + class Post < Struct.new(:author_name, :body, :updated_at) include ActiveModel::Conversion include ActiveModel::Validations @@ -20,9 +20,11 @@ class ActiveModelHelperTest < ActionView::TestCase @post = Post.new @post.errors[:author_name] << "can't be empty" @post.errors[:body] << "foo" + @post.errors[:updated_at] << "bar" @post.author_name = "" @post.body = "Back to the hill and over it again!" + @post.updated_at = Date.new(2004, 6, 15) end def test_text_area_with_errors @@ -39,6 +41,27 @@ class ActiveModelHelperTest < ActionView::TestCase ) end + def test_date_select_with_errors + assert_dom_equal( + %(<div class="field_with_errors"><select id="post_updated_at_1i" name="post[updated_at(1i)]">\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n</select>\n<input id="post_updated_at_2i" name="post[updated_at(2i)]" type="hidden" value="6" />\n<input id="post_updated_at_3i" name="post[updated_at(3i)]" type="hidden" value="15" />\n</div>), + date_select("post", "updated_at", :discard_month => true, :discard_day => true, :start_year => 2004, :end_year => 2005) + ) + end + + def test_datetime_select_with_errors + assert_dom_equal( + %(<div class="field_with_errors"><input id="post_updated_at_1i" name="post[updated_at(1i)]" type="hidden" value="2004" />\n<input id="post_updated_at_2i" name="post[updated_at(2i)]" type="hidden" value="6" />\n<input id="post_updated_at_3i" name="post[updated_at(3i)]" type="hidden" value="15" />\n<select id="post_updated_at_4i" name="post[updated_at(4i)]">\n<option selected="selected" value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n</select>\n : <select id="post_updated_at_5i" name="post[updated_at(5i)]">\n<option selected="selected" value="00">00</option>\n</select>\n</div>), + datetime_select("post", "updated_at", :discard_year => true, :discard_month => true, :discard_day => true, :minute_step => 60) + ) + end + + def test_time_select_with_errors + assert_dom_equal( + %(<div class="field_with_errors"><input id="post_updated_at_1i" name="post[updated_at(1i)]" type="hidden" value="2004" />\n<input id="post_updated_at_2i" name="post[updated_at(2i)]" type="hidden" value="6" />\n<input id="post_updated_at_3i" name="post[updated_at(3i)]" type="hidden" value="15" />\n<select id="post_updated_at_4i" name="post[updated_at(4i)]">\n<option selected="selected" value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n</select>\n : <select id="post_updated_at_5i" name="post[updated_at(5i)]">\n<option selected="selected" value="00">00</option>\n</select>\n</div>), + time_select("post", "updated_at", :minute_step => 60) + ) + end + def test_hidden_field_does_not_render_errors assert_dom_equal( %(<input id="post_author_name" name="post[author_name]" type="hidden" value="" />), diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb index 13e2d5b595..a37e3a8d6a 100644 --- a/actionpack/test/template/capture_helper_test.rb +++ b/actionpack/test/template/capture_helper_test.rb @@ -131,17 +131,15 @@ class CaptureHelperTest < ActionView::TestCase assert buffer.equal?(@av.output_buffer) end - unless RUBY_VERSION < '1.9' - def test_with_output_buffer_sets_proper_encoding - @av.output_buffer = ActionView::OutputBuffer.new + def test_with_output_buffer_sets_proper_encoding + @av.output_buffer = ActionView::OutputBuffer.new - # Ensure we set the output buffer to an encoding different than the default one. - alt_encoding = alt_encoding(@av.output_buffer) - @av.output_buffer.force_encoding(alt_encoding) + # Ensure we set the output buffer to an encoding different than the default one. + alt_encoding = alt_encoding(@av.output_buffer) + @av.output_buffer.force_encoding(alt_encoding) - @av.with_output_buffer do - assert_equal alt_encoding, @av.output_buffer.encoding - end + @av.with_output_buffer do + assert_equal alt_encoding, @av.output_buffer.encoding end end @@ -165,14 +163,12 @@ class CaptureHelperTest < ActionView::TestCase assert_equal '', view.output_buffer end - unless RUBY_VERSION < '1.9' - def test_flush_output_buffer_preserves_the_encoding_of_the_output_buffer - view = view_with_controller - alt_encoding = alt_encoding(view.output_buffer) - view.output_buffer.force_encoding(alt_encoding) - flush_output_buffer - assert_equal alt_encoding, view.output_buffer.encoding - end + def test_flush_output_buffer_preserves_the_encoding_of_the_output_buffer + view = view_with_controller + alt_encoding = alt_encoding(view.output_buffer) + view.output_buffer.force_encoding(alt_encoding) + flush_output_buffer + assert_equal alt_encoding, view.output_buffer.encoding end def alt_encoding(output_buffer) diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index 469718e1bd..4a889beadd 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -596,6 +596,24 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_select_with_nil + @post = Post.new + @post.category = "othervalue" + assert_dom_equal( + "<select id=\"post_category\" name=\"post[category]\"><option value=\"\"></option>\n<option value=\"othervalue\" selected=\"selected\">othervalue</option></select>", + select("post", "category", [nil, "othervalue"]) + ) + end + + def test_select_with_fixnum + @post = Post.new + @post.category = "" + assert_dom_equal( + "<select id=\"post_category\" name=\"post[category]\"><option value=\"\">Please select</option>\n<option value=\"\"></option>\n<option value=\"1\">1</option></select>", + select("post", "category", [1], :prompt => true, :include_blank => true) + ) + end + def test_list_of_lists @post = Post.new @post.category = "" diff --git a/actionpack/test/template/output_safety_helper_test.rb b/actionpack/test/template/output_safety_helper_test.rb index fc127c24e9..76c71c9e6d 100644 --- a/actionpack/test/template/output_safety_helper_test.rb +++ b/actionpack/test/template/output_safety_helper_test.rb @@ -1,9 +1,7 @@ require 'abstract_unit' -require 'testing_sandbox' class OutputSafetyHelperTest < ActionView::TestCase tests ActionView::Helpers::OutputSafetyHelper - include TestingSandbox def setup @string = "hello" diff --git a/actionpack/test/template/sanitize_helper_test.rb b/actionpack/test/template/sanitize_helper_test.rb index 222d4dbf4c..4182af590e 100644 --- a/actionpack/test/template/sanitize_helper_test.rb +++ b/actionpack/test/template/sanitize_helper_test.rb @@ -1,11 +1,9 @@ require 'abstract_unit' -require 'testing_sandbox' # The exhaustive tests are in test/controller/html/sanitizer_test.rb. # This tests the that the helpers hook up correctly to the sanitizer classes. class SanitizeHelperTest < ActionView::TestCase tests ActionView::Helpers::SanitizeHelper - include TestingSandbox def test_strip_links assert_equal "Dont touch me", strip_links("Dont touch me") diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb index a0afb77f05..839bf900dc 100644 --- a/actionpack/test/template/text_helper_test.rb +++ b/actionpack/test/template/text_helper_test.rb @@ -1,10 +1,8 @@ # encoding: utf-8 require 'abstract_unit' -require 'testing_sandbox' class TextHelperTest < ActionView::TestCase tests ActionView::Helpers::TextHelper - include TestingSandbox def setup super @@ -82,25 +80,13 @@ class TextHelperTest < ActionView::TestCase assert_equal "Hello Big[...]", truncate("Hello Big World!", :omission => "[...]", :length => 15, :separator => ' ') end - if RUBY_VERSION < '1.9.0' - def test_truncate_multibyte - with_kcode 'none' do - assert_equal "\354\225\210\353\205\225\355...", truncate("\354\225\210\353\205\225\355\225\230\354\204\270\354\232\224", :length => 10) - end - with_kcode 'u' do - assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...", - truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244", :length => 10) - end - end - else - def test_truncate_multibyte - # .mb_chars always returns a UTF-8 String. - # assert_equal "\354\225\210\353\205\225\355...", - # truncate("\354\225\210\353\205\225\355\225\230\354\204\270\354\232\224", :length => 10) + def test_truncate_multibyte + # .mb_chars always returns a UTF-8 String. + # assert_equal "\354\225\210\353\205\225\355...", + # truncate("\354\225\210\353\205\225\355\225\230\354\204\270\354\232\224", :length => 10) - assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8'), - truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8'), :length => 10) - end + assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8'), + truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8'), :length => 10) end def test_highlight_should_be_html_safe @@ -243,21 +229,10 @@ class TextHelperTest < ActionView::TestCase ) end - if RUBY_VERSION < '1.9' - def test_excerpt_with_utf8 - with_kcode('u') do - assert_equal("...\357\254\203ciency could not be...", excerpt("That's why e\357\254\203ciency could not be helped", 'could', 8)) - end - with_kcode('none') do - assert_equal("...\203ciency could not be...", excerpt("That's why e\357\254\203ciency could not be helped", 'could', 8)) - end - end - else - def test_excerpt_with_utf8 - assert_equal("...\357\254\203ciency could not be...".force_encoding('UTF-8'), excerpt("That's why e\357\254\203ciency could not be helped".force_encoding('UTF-8'), 'could', 8)) - # .mb_chars always returns UTF-8, even in 1.9. This is not great, but it's how it works. Let's work this out. - # assert_equal("...\203ciency could not be...", excerpt("That's why e\357\254\203ciency could not be helped".force_encoding("BINARY"), 'could', 8)) - end + def test_excerpt_with_utf8 + assert_equal("...\357\254\203ciency could not be...".force_encoding('UTF-8'), excerpt("That's why e\357\254\203ciency could not be helped".force_encoding('UTF-8'), 'could', 8)) + # .mb_chars always returns UTF-8, even in 1.9. This is not great, but it's how it works. Let's work this out. + # assert_equal("...\203ciency could not be...", excerpt("That's why e\357\254\203ciency could not be helped".force_encoding("BINARY"), 'could', 8)) end def test_word_wrap diff --git a/activemodel/activemodel.gemspec b/activemodel/activemodel.gemspec index 283c3ee324..60c1d16934 100644 --- a/activemodel/activemodel.gemspec +++ b/activemodel/activemodel.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| s.summary = 'A toolkit for building modeling frameworks (part of Rails).' s.description = 'A toolkit for building modeling frameworks like Active Record and Active Resource. Rich support for attributes, callbacks, validations, observers, serialization, internationalization, and testing.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' diff --git a/activemodel/lib/active_model/locale/en.yml b/activemodel/lib/active_model/locale/en.yml index 44425b4a28..ba49c6beaa 100644 --- a/activemodel/lib/active_model/locale/en.yml +++ b/activemodel/lib/active_model/locale/en.yml @@ -23,5 +23,6 @@ en: equal_to: "must be equal to %{count}" less_than: "must be less than %{count}" less_than_or_equal_to: "must be less than or equal to %{count}" + other_than: "must be other than %{count}" odd: "must be odd" even: "must be even" diff --git a/activemodel/lib/active_model/test_case.rb b/activemodel/lib/active_model/test_case.rb index 6328807ad7..5004855d56 100644 --- a/activemodel/lib/active_model/test_case.rb +++ b/activemodel/lib/active_model/test_case.rb @@ -1,16 +1,4 @@ module ActiveModel #:nodoc: class TestCase < ActiveSupport::TestCase #:nodoc: - def with_kcode(kcode) - if RUBY_VERSION < '1.9' - orig_kcode, $KCODE = $KCODE, kcode - begin - yield - ensure - $KCODE = orig_kcode - end - else - yield - end - end end end diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index 34d447a0fa..bb9f9679fc 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -5,7 +5,7 @@ module ActiveModel class NumericalityValidator < EachValidator CHECKS = { :greater_than => :>, :greater_than_or_equal_to => :>=, :equal_to => :==, :less_than => :<, :less_than_or_equal_to => :<=, - :odd => :odd?, :even => :even? }.freeze + :odd => :odd?, :even => :even?, :other_than => :!= }.freeze RESERVED_OPTIONS = CHECKS.keys + [:only_integer] @@ -99,6 +99,7 @@ module ActiveModel # * <tt>:equal_to</tt> - Specifies the value must be equal to the supplied value. # * <tt>:less_than</tt> - Specifies the value must be less than the supplied value. # * <tt>:less_than_or_equal_to</tt> - Specifies the value must be less than or equal the supplied value. + # * <tt>:other_than</tt> - Specifies the value must be other than the supplied value. # * <tt>:odd</tt> - Specifies the value must be an odd number. # * <tt>:even</tt> - Specifies the value must be an even number. # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should @@ -107,7 +108,7 @@ module ActiveModel # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The # method, proc or string should return or evaluate to a true or false value. - # * <tt>:strict</tt> - Specifies whether validation should be strict. + # * <tt>:strict</tt> - Specifies whether validation should be strict. # See <tt>ActiveModel::Validation#validates!</tt> for more information # # The following checks can also be supplied with a proc or a symbol which corresponds to a method: diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index 44048a9c1d..aa86d9d959 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -260,74 +260,64 @@ class LengthValidationTest < ActiveModel::TestCase end def test_validates_length_of_using_minimum_utf8 - with_kcode('UTF8') do - Topic.validates_length_of :title, :minimum => 5 + Topic.validates_length_of :title, :minimum => 5 - t = Topic.new("title" => "一二三四五", "content" => "whatever") - assert t.valid? + t = Topic.new("title" => "一二三四五", "content" => "whatever") + assert t.valid? - t.title = "一二三四" - assert t.invalid? - assert t.errors[:title].any? - assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"] - end + t.title = "一二三四" + assert t.invalid? + assert t.errors[:title].any? + assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"] end def test_validates_length_of_using_maximum_utf8 - with_kcode('UTF8') do - Topic.validates_length_of :title, :maximum => 5 + Topic.validates_length_of :title, :maximum => 5 - t = Topic.new("title" => "一二三四五", "content" => "whatever") - assert t.valid? + t = Topic.new("title" => "一二三四五", "content" => "whatever") + assert t.valid? - t.title = "一二34五六" - assert t.invalid? - assert t.errors[:title].any? - assert_equal ["is too long (maximum is 5 characters)"], t.errors["title"] - end + t.title = "一二34五六" + assert t.invalid? + assert t.errors[:title].any? + assert_equal ["is too long (maximum is 5 characters)"], t.errors["title"] end def test_validates_length_of_using_within_utf8 - with_kcode('UTF8') do - Topic.validates_length_of(:title, :content, :within => 3..5) - - t = Topic.new("title" => "一二", "content" => "12三四五六七") - assert t.invalid? - assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] - assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content] - t.title = "一二三" - t.content = "12三" - assert t.valid? - end + Topic.validates_length_of(:title, :content, :within => 3..5) + + t = Topic.new("title" => "一二", "content" => "12三四五六七") + assert t.invalid? + assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] + assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content] + t.title = "一二三" + t.content = "12三" + assert t.valid? end def test_optionally_validates_length_of_using_within_utf8 - with_kcode('UTF8') do - Topic.validates_length_of :title, :within => 3..5, :allow_nil => true + Topic.validates_length_of :title, :within => 3..5, :allow_nil => true - t = Topic.new(:title => "一二三四五") - assert t.valid?, t.errors.inspect + t = Topic.new(:title => "一二三四五") + assert t.valid?, t.errors.inspect - t = Topic.new(:title => "一二三") - assert t.valid?, t.errors.inspect + t = Topic.new(:title => "一二三") + assert t.valid?, t.errors.inspect - t.title = nil - assert t.valid?, t.errors.inspect - end + t.title = nil + assert t.valid?, t.errors.inspect end def test_validates_length_of_using_is_utf8 - with_kcode('UTF8') do - Topic.validates_length_of :title, :is => 5 + Topic.validates_length_of :title, :is => 5 - t = Topic.new("title" => "一二345", "content" => "whatever") - assert t.valid? + t = Topic.new("title" => "一二345", "content" => "whatever") + assert t.valid? - t.title = "一二345六" - assert t.invalid? - assert t.errors[:title].any? - assert_equal ["is the wrong length (should be 5 characters)"], t.errors["title"] - end + t.title = "一二345六" + assert t.invalid? + assert t.errors[:title].any? + assert_equal ["is the wrong length (should be 5 characters)"], t.errors["title"] end def test_validates_length_of_with_block diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index 08f6169ca5..6742a4bab0 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -106,6 +106,13 @@ class NumericalityValidationTest < ActiveModel::TestCase valid!([2]) end + def test_validates_numericality_with_other_than + Topic.validates_numericality_of :approved, :other_than => 0 + + invalid!([0, 0.0]) + valid!([-1, 42]) + end + def test_validates_numericality_with_proc Topic.send(:define_method, :min_approved, lambda { 5 }) Topic.validates_numericality_of :approved, :greater_than_or_equal_to => Proc.new {|topic| topic.min_approved } diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index cd8e50b33a..ee2811c2be 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +## Rails 4.0.0 (unreleased) ## + +* PostgreSQL hstore records can be created. + +* PostgreSQL hstore types are automatically deserialized from the database. + ## Rails 3.2.0 (unreleased) ## * Added ability to run migrations only for given scope, which allows @@ -147,10 +153,6 @@ *Aaron Christy* -* Add ActiveSupport::Cache::NullStore for use in development and testing. - - *Brian Durand* - ## Rails 3.1.3 (unreleased) ## * Perf fix: If we're deleting all records in an association, don't add a IN(..) clause diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec index b6a8db1ac0..4a889c1340 100644 --- a/activerecord/activerecord.gemspec +++ b/activerecord/activerecord.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| s.summary = 'Object-relational mapper framework (part of Rails).' s.description = 'Databases on Rails. Build a persistent domain model by mapping database tables to Ruby classes. Strong conventions for associations, validations, aggregations, migrations, and testing come baked-in.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb index a7856539b7..6aa4a2c5b3 100644 --- a/activerecord/lib/active_record/connection_adapters/column.rb +++ b/activerecord/lib/active_record/connection_adapters/column.rb @@ -80,9 +80,10 @@ module ActiveRecord when :decimal then klass.value_to_decimal(value) when :datetime, :timestamp then klass.string_to_time(value) when :time then klass.string_to_dummy_time(value) - when :date then klass.string_to_date(value) + when :date then klass.value_to_date(value) when :binary then klass.binary_to_string(value) when :boolean then klass.value_to_boolean(value) + when :hstore then klass.cast_hstore(value) else value end end @@ -97,9 +98,10 @@ module ActiveRecord when :decimal then "#{klass}.value_to_decimal(#{var_name})" when :datetime, :timestamp then "#{klass}.string_to_time(#{var_name})" when :time then "#{klass}.string_to_dummy_time(#{var_name})" - when :date then "#{klass}.string_to_date(#{var_name})" + when :date then "#{klass}.value_to_date(#{var_name})" when :binary then "#{klass}.binary_to_string(#{var_name})" when :boolean then "#{klass}.value_to_boolean(#{var_name})" + when :hstore then "#{klass}.cast_hstore(#{var_name})" else var_name end end @@ -132,11 +134,15 @@ module ActiveRecord value end - def string_to_date(string) - return string unless string.is_a?(String) - return nil if string.empty? - - fast_string_to_date(string) || fallback_string_to_date(string) + def value_to_date(value) + if value.is_a?(String) + return nil if value.empty? + fast_string_to_date(value) || fallback_string_to_date(value) + elsif value.respond_to?(:to_date) + value.to_date + else + value + end end def string_to_time(string) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 6b742ed858..d7adcdc5d4 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -49,6 +49,42 @@ module ActiveRecord super end end + + def cast_hstore(object) + if Hash === object + object.map { |k,v| + "#{escape_hstore(k)}=>#{escape_hstore(v)}" + }.join ', ' + else + kvs = object.scan(/(?<!\\)".*?(?<!\\)"/).map { |o| + unescape_hstore(o[1...-1]) + } + Hash[kvs.each_slice(2).to_a] + end + end + + private + HSTORE_ESCAPE = { + ' ' => '\\ ', + '\\' => '\\\\', + '"' => '\\"', + '=' => '\\=', + } + HSTORE_ESCAPE_RE = Regexp.union(HSTORE_ESCAPE.keys) + HSTORE_UNESCAPE = HSTORE_ESCAPE.invert + HSTORE_UNESCAPE_RE = Regexp.union(HSTORE_UNESCAPE.keys) + + def unescape_hstore(value) + value.gsub(HSTORE_UNESCAPE_RE) do |match| + HSTORE_UNESCAPE[match] + end + end + + def escape_hstore(value) + value.gsub(HSTORE_ESCAPE_RE) do |match| + HSTORE_ESCAPE[match] + end + end end # :startdoc: @@ -79,53 +115,55 @@ module ActiveRecord # Maps PostgreSQL-specific data types to logical Rails types. def simplified_type(field_type) case field_type - # Numeric and monetary types - when /^(?:real|double precision)$/ - :float - # Monetary types - when 'money' - :decimal - # Character types - when /^(?:character varying|bpchar)(?:\(\d+\))?$/ - :string - # Binary data types - when 'bytea' - :binary - # Date/time types - when /^timestamp with(?:out)? time zone$/ - :datetime - when 'interval' - :string - # Geometric types - when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ - :string - # Network address types - when /^(?:cidr|inet|macaddr)$/ - :string - # Bit strings - when /^bit(?: varying)?(?:\(\d+\))?$/ - :string - # XML type - when 'xml' - :xml - # tsvector type - when 'tsvector' - :tsvector - # Arrays - when /^\D+\[\]$/ - :string - # Object identifier types - when 'oid' - :integer - # UUID type - when 'uuid' - :string - # Small and big integer types - when /^(?:small|big)int$/ - :integer - # Pass through all types that are not specific to PostgreSQL. - else - super + # Numeric and monetary types + when /^(?:real|double precision)$/ + :float + # Monetary types + when 'money' + :decimal + when 'hstore' + :hstore + # Character types + when /^(?:character varying|bpchar)(?:\(\d+\))?$/ + :string + # Binary data types + when 'bytea' + :binary + # Date/time types + when /^timestamp with(?:out)? time zone$/ + :datetime + when 'interval' + :string + # Geometric types + when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ + :string + # Network address types + when /^(?:cidr|inet|macaddr)$/ + :string + # Bit strings + when /^bit(?: varying)?(?:\(\d+\))?$/ + :string + # XML type + when 'xml' + :xml + # tsvector type + when 'tsvector' + :tsvector + # Arrays + when /^\D+\[\]$/ + :string + # Object identifier types + when 'oid' + :integer + # UUID type + when 'uuid' + :string + # Small and big integer types + when /^(?:small|big)int$/ + :integer + # Pass through all types that are not specific to PostgreSQL. + else + super end end @@ -215,6 +253,10 @@ module ActiveRecord options = args.extract_options! column(args[0], 'tsvector', options) end + + def hstore(name, options = {}) + column(name, 'hstore', options) + end end ADAPTER_NAME = 'PostgreSQL' diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb index 9840cbccae..6b5070808a 100644 --- a/activerecord/lib/active_record/scoping/default.rb +++ b/activerecord/lib/active_record/scoping/default.rb @@ -12,7 +12,7 @@ module ActiveRecord end module ClassMethods - # Returns a scope for this class without taking into account the default_scope. + # Returns a scope for the model without the default_scope. # # class Post < ActiveRecord::Base # def self.default_scope @@ -23,18 +23,20 @@ module ActiveRecord # Post.all # Fires "SELECT * FROM posts WHERE published = true" # Post.unscoped.all # Fires "SELECT * FROM posts" # - # This method also accepts a block meaning that all queries inside the block will + # This method also accepts a block. All queries inside the block will # not use the default_scope: # # Post.unscoped { # Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10" # } # - # It is recommended to use block form of unscoped because chaining unscoped with <tt>scope</tt> - # does not work. Assuming that <tt>published</tt> is a <tt>scope</tt> following two statements are same. + # It is recommended to use the block form of unscoped because chaining + # unscoped with <tt>scope</tt> does not work. Assuming that + # <tt>published</tt> is a <tt>scope</tt>, the following two statements + # are equal: the default_scope is applied on both. # - # Post.unscoped.published - # Post.published + # Post.unscoped.published + # Post.published def unscoped #:nodoc: block_given? ? relation.scoping { yield } : relation end diff --git a/activerecord/lib/active_record/test_case.rb b/activerecord/lib/active_record/test_case.rb index ffe9b08dce..21aff475a8 100644 --- a/activerecord/lib/active_record/test_case.rb +++ b/activerecord/lib/active_record/test_case.rb @@ -56,18 +56,5 @@ module ActiveRecord ensure ActiveRecord::SQLCounter.ignored_sql = prev_ignored_sql end - - def with_kcode(kcode) - if RUBY_VERSION < '1.9' - orig_kcode, $KCODE = $KCODE, kcode - begin - yield - ensure - $KCODE = orig_kcode - end - else - yield - end - end end end diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb new file mode 100644 index 0000000000..33bf4478cc --- /dev/null +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -0,0 +1,89 @@ +require "cases/helper" + +class PostgresqlHstoreTest < ActiveRecord::TestCase + class Hstore < ActiveRecord::Base + self.table_name = 'hstores' + end + + def setup + @connection = ActiveRecord::Base.connection + begin + @connection.transaction do + @connection.create_table('hstores') do |t| + t.hstore 'tags' + end + end + rescue ActiveRecord::StatementInvalid + return skip "do not test on PG without hstore" + end + end + + def teardown + @connection.execute 'drop table if exists hstores' + end + + def test_column + column = Hstore.columns.find { |c| c.name == 'tags' } + assert column + assert_equal :hstore, column.type + end + + def test_type_cast_hstore + column = Hstore.columns.find { |c| c.name == 'tags' } + assert column + + data = "\"1\"=>\"2\"" + hash = column.class.cast_hstore data + assert_equal({'1' => '2'}, hash) + assert_equal({'1' => '2'}, column.type_cast(data)) + end + + def test_select + @connection.execute "insert into hstores (tags) VALUES ('1=>2')" + x = Hstore.find :first + assert_equal({'1' => '2'}, x.tags) + end + + def test_select_multikey + @connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')" + x = Hstore.find :first + assert_equal({'1' => '2', '2' => '3'}, x.tags) + end + + def test_create + assert_cycle('a' => 'b', '1' => '2') + end + + def test_quotes + assert_cycle('a' => 'b"ar', '1"foo' => '2') + end + + def test_whitespace + assert_cycle('a b' => 'b ar', '1"foo' => '2') + end + + def test_backslash + assert_cycle('a\\b' => 'b\\ar', '1"foo' => '2') + end + + def test_comma + assert_cycle('a, b' => 'bar', '1"foo' => '2') + end + + def test_arrow + assert_cycle('a=>b' => 'bar', '1"foo' => '2') + end + + private + def assert_cycle hash + x = Hstore.create!(:tags => hash) + x.reload + assert_equal(hash, x.tags) + + # make sure updates work + x.tags = hash + x.save! + x.reload + assert_equal(hash, x.tags) + end +end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 1dc71ac4cc..3d759e64f8 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1095,4 +1095,11 @@ class EagerAssociationTest < ActiveRecord::TestCase Post.includes(:comments).order(nil).where(:comments => {:body => "Thank you for the welcome"}).first end end + + def test_deep_including_through_habtm + posts = Post.find(:all, :include => {:categories => :categorizations}, :order => "posts.id") + assert_no_queries { assert_equal 2, posts[0].categories[0].categorizations.length } + assert_no_queries { assert_equal 1, posts[0].categories[1].categorizations.length } + assert_no_queries { assert_equal 2, posts[1].categories[0].categorizations.length } + end end diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb index 395b59258d..d7c489c2b5 100644 --- a/activerecord/test/cases/associations/extension_test.rb +++ b/activerecord/test/cases/associations/extension_test.rb @@ -36,11 +36,6 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase end def test_marshalling_extensions - if ENV['TRAVIS'] && RUBY_VERSION == "1.8.7" - return skip("Marshalling tests disabled for Ruby 1.8.7 on Travis CI due to what appears " \ - "to be a Ruby bug.") - end - david = developers(:david) assert_equal projects(:action_controller), david.projects.find_most_recent @@ -51,11 +46,6 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase end def test_marshalling_named_extensions - if ENV['TRAVIS'] && RUBY_VERSION == "1.8.7" - return skip("Marshalling tests disabled for Ruby 1.8.7 on Travis CI due to what appears " \ - "to be a Ruby bug.") - end - david = developers(:david) assert_equal projects(:action_controller), david.projects_extended_by_name.find_most_recent diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 39e58559b0..5e9f8028e9 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -518,6 +518,14 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end + def test_write_time_to_date_attributes + in_time_zone "Pacific Time (US & Canada)" do + record = @target.new + record.last_read = Time.utc(2010, 1, 1, 10) + assert_equal Date.civil(2010, 1, 1), record.last_read + end + end + def test_time_attributes_are_retrieved_in_current_time_zone in_time_zone "Pacific Time (US & Canada)" do utc_time = Time.utc(2008, 1, 1) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 1012bfbd94..2e2ab77f6e 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1357,22 +1357,6 @@ class BasicsTest < ActiveRecord::TestCase assert_equal author_name, Topic.find(topic.id).author_name end - if RUBY_VERSION < '1.9' - def test_quote_chars - with_kcode('UTF8') do - str = 'The Narrator' - topic = Topic.create(:author_name => str) - assert_equal str, topic.author_name - - assert_kind_of ActiveSupport::Multibyte.proxy_class, str.mb_chars - topic = Topic.find_by_author_name(str.mb_chars) - - assert_kind_of Topic, topic - assert_equal str, topic.author_name, "The right topic should have been found by name even with name passed as Chars" - end - end - end - def test_toggle_attribute assert !topics(:first).approved? topics(:first).toggle!(:approved) @@ -1914,7 +1898,7 @@ class BasicsTest < ActiveRecord::TestCase def test_benchmark_with_log_level original_logger = ActiveRecord::Base.logger log = StringIO.new - ActiveRecord::Base.logger = Logger.new(log) + ActiveRecord::Base.logger = ActiveSupport::Logger.new(log) ActiveRecord::Base.logger.level = Logger::WARN ActiveRecord::Base.benchmark("Debug Topic Count", :level => :debug) { Topic.count } ActiveRecord::Base.benchmark("Warn Topic Count", :level => :warn) { Topic.count } @@ -1929,7 +1913,7 @@ class BasicsTest < ActiveRecord::TestCase def test_benchmark_with_use_silence original_logger = ActiveRecord::Base.logger log = StringIO.new - ActiveRecord::Base.logger = Logger.new(log) + ActiveRecord::Base.logger = ActiveSupport::Logger.new(log) ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => false) { ActiveRecord::Base.logger.debug "Quiet" } assert_match(/Quiet/, log.string) ensure @@ -1981,11 +1965,6 @@ class BasicsTest < ActiveRecord::TestCase end def test_marshal_round_trip - if ENV['TRAVIS'] && RUBY_VERSION == "1.8.7" - return skip("Marshalling tests disabled for Ruby 1.8.7 on Travis CI due to what appears " \ - "to be a Ruby bug.") - end - expected = posts(:welcome) marshalled = Marshal.dump(expected) actual = Marshal.load(marshalled) @@ -1994,11 +1973,6 @@ class BasicsTest < ActiveRecord::TestCase end def test_marshal_new_record_round_trip - if ENV['TRAVIS'] && RUBY_VERSION == "1.8.7" - return skip("Marshalling tests disabled for Ruby 1.8.7 on Travis CI due to what appears " \ - "to be a Ruby bug.") - end - marshalled = Marshal.dump(Post.new) post = Marshal.load(marshalled) @@ -2006,11 +1980,6 @@ class BasicsTest < ActiveRecord::TestCase end def test_marshalling_with_associations - if ENV['TRAVIS'] && RUBY_VERSION == "1.8.7" - return skip("Marshalling tests disabled for Ruby 1.8.7 on Travis CI due to what appears " \ - "to be a Ruby bug.") - end - post = Post.new post.comments.build diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index be7edb858f..5978b244d4 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -421,16 +421,6 @@ unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db? assert first.end > second.end end - # Hit by ruby deadlock detection since connection checkout is mutexed. - if RUBY_VERSION < '1.9.0' - def test_second_lock_waits - assert [0.2, 1, 5].any? { |zzz| - first, second = duel(zzz) { Person.find 1, :lock => true } - second.end > first.end - } - end - end - protected def duel(zzz = 5) t0, t1, t2, t3 = nil, nil, nil, nil diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb index bc3dfb1078..296621c0d1 100644 --- a/activerecord/test/cases/pooled_connections_test.rb +++ b/activerecord/test/cases/pooled_connections_test.rb @@ -33,14 +33,6 @@ class PooledConnectionsTest < ActiveRecord::TestCase end # Will deadlock due to lack of Monitor timeouts in 1.9 - if RUBY_VERSION < '1.9' - def test_pooled_connection_checkout - checkout_connections - assert_equal 2, @connections.length - assert_equal 2, @timed_out - end - end - def checkout_checkin_connections(pool_size, threads) ActiveRecord::Base.establish_connection(@connection.merge({:pool => pool_size, :wait_timeout => 0.5})) @connection_count = 0 diff --git a/activerecord/test/cases/validations/association_validation_test.rb b/activerecord/test/cases/validations/association_validation_test.rb index 768fbc5b0a..f155b9bc40 100644 --- a/activerecord/test/cases/validations/association_validation_test.rb +++ b/activerecord/test/cases/validations/association_validation_test.rb @@ -91,14 +91,12 @@ class AssociationValidationTest < ActiveRecord::TestCase end def test_validates_size_of_association_utf8 - with_kcode('UTF8') do - assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } - o = Owner.new('name' => 'あいうえおかきくけこ') - assert !o.save - assert o.errors[:pets].any? - o.pets.build('name' => 'あいうえおかきくけこ') - assert o.valid? - end + assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 } + o = Owner.new('name' => 'あいうえおかきくけこ') + assert !o.save + assert o.errors[:pets].any? + o.pets.build('name' => 'あいうえおかきくけこ') + assert o.valid? end def test_validates_presence_of_belongs_to_association__parent_is_new_record diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb index 0f1b3667cc..382ad0a06a 100644 --- a/activerecord/test/cases/validations/uniqueness_validation_test.rb +++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb @@ -149,16 +149,14 @@ class UniquenessValidationTest < ActiveRecord::TestCase assert t2.valid?, "should validate with nil" assert t2.save, "should save with nil" - with_kcode('UTF8') do - t_utf8 = Topic.new("title" => "Я тоже уникальный!") - assert t_utf8.save, "Should save t_utf8 as unique" - - # If database hasn't UTF-8 character set, this test fails - if Topic.find(t_utf8, :select => 'LOWER(title) AS title').title == "я тоже уникальный!" - t2_utf8 = Topic.new("title" => "я тоже УНИКАЛЬНЫЙ!") - assert !t2_utf8.valid?, "Shouldn't be valid" - assert !t2_utf8.save, "Shouldn't save t2_utf8 as unique" - end + t_utf8 = Topic.new("title" => "Я тоже уникальный!") + assert t_utf8.save, "Should save t_utf8 as unique" + + # If database hasn't UTF-8 character set, this test fails + if Topic.find(t_utf8, :select => 'LOWER(title) AS title').title == "я тоже уникальный!" + t2_utf8 = Topic.new("title" => "я тоже УНИКАЛЬНЫЙ!") + assert !t2_utf8.valid?, "Shouldn't be valid" + assert !t2_utf8.save, "Shouldn't save t2_utf8 as unique" end end @@ -256,13 +254,11 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_limit_and_utf8 - with_kcode('UTF8') do - # Event.title is limited to 5 characters - e1 = Event.create(:title => "一二三四五") - assert e1.valid?, "Could not create an event with a unique, 5 character title" - e2 = Event.create(:title => "一二三四五六七八") - assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique" - end + # Event.title is limited to 5 characters + e1 = Event.create(:title => "一二三四五") + assert e1.valid?, "Could not create an event with a unique, 5 character title" + e2 = Event.create(:title => "一二三四五六七八") + assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique" end def test_validate_straight_inheritance_uniqueness diff --git a/activeresource/activeresource.gemspec b/activeresource/activeresource.gemspec index f5c26f38df..ae1972a7d7 100644 --- a/activeresource/activeresource.gemspec +++ b/activeresource/activeresource.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| s.summary = 'REST modeling framework (part of Rails).' s.description = 'REST on Rails. Wrap your RESTful web app with Ruby classes and work with them like Active Record models.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index 10cc727bd9..548990cb70 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -1413,7 +1413,7 @@ module ActiveResource namespaces = module_names[0, module_names.size-1].map do |module_name| receiver = receiver.const_get(module_name) end - const_args = RUBY_VERSION < "1.9" ? [resource_name] : [resource_name, false] + const_args = [resource_name, false] if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(*const_args) } namespace.const_get(*const_args) else @@ -1425,7 +1425,7 @@ module ActiveResource def find_or_create_resource_for(name) resource_name = name.to_s.camelize - const_args = RUBY_VERSION < "1.9" ? [resource_name] : [resource_name, false] + const_args = [resource_name, false] if self.class.const_defined?(*const_args) self.class.const_get(*const_args) else diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 8299a3fc45..f23ee6e045 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -5,6 +5,8 @@ ## Rails 3.2.0 (unreleased) ## +* Add ActiveSupport::Cache::NullStore for use in development and testing. *Brian Durand* + * Added Enumerable#pluck to wrap the common pattern of collect(&:method) *DHH* * Module#synchronize is deprecated with no replacement. Please use `monitor` diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec index 70d17fb580..4db22a0dbd 100644 --- a/activesupport/activesupport.gemspec +++ b/activesupport/activesupport.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| s.summary = 'A toolkit of support libraries and Ruby core extensions extracted from the Rails framework.' s.description = 'A toolkit of support libraries and Ruby core extensions extracted from the Rails framework. Rich support for multibyte strings, internationalization, time zones, and testing.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' diff --git a/activesupport/lib/active_support/base64.rb b/activesupport/lib/active_support/base64.rb index 35014cb3d5..b43d2ce9a3 100644 --- a/activesupport/lib/active_support/base64.rb +++ b/activesupport/lib/active_support/base64.rb @@ -1,35 +1,7 @@ -begin - require 'base64' -rescue LoadError -end +require 'base64' module ActiveSupport - if defined? ::Base64 - Base64 = ::Base64 - else - # Base64 provides utility methods for encoding and de-coding binary data - # using a base 64 representation. A base 64 representation of binary data - # consists entirely of printable US-ASCII characters. The Base64 module - # is included in Ruby 1.8, but has been removed in Ruby 1.9. - module Base64 - # Encodes a string to its base 64 representation. Each 60 characters of - # output is separated by a newline character. - # - # ActiveSupport::Base64.encode64("Original unencoded string") - # # => "T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw==\n" - def self.encode64(data) - [data].pack("m") - end - - # Decodes a base 64 encoded string to its original representation. - # - # ActiveSupport::Base64.decode64("T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw==") - # # => "Original unencoded string" - def self.decode64(data) - data.unpack("m").first - end - end - end + Base64 = ::Base64 # Encodes the value as base64 without the newline breaks. This makes the base64 encoding readily usable as URL parameters # or memcache keys without further processing. diff --git a/activesupport/lib/active_support/core_ext/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb index 4cd9bfadac..2b3f639cb1 100644 --- a/activesupport/lib/active_support/core_ext/array/grouping.rb +++ b/activesupport/lib/active_support/core_ext/array/grouping.rb @@ -1,5 +1,3 @@ -require 'enumerator' - class Array # Splits or iterates over the array in groups of size +number+, # padding any remaining slots with +fill_with+ unless it is +false+. diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index f0f67765c6..2212e0b3ca 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -7,24 +7,6 @@ require 'active_support/core_ext/time/zones' class Date DAYS_INTO_WEEK = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6 } - if RUBY_VERSION < '1.9' - undef :>> - - # Backported from 1.9. The one in 1.8 leads to incorrect next_month and - # friends for dates where the calendar reform is involved. It additionally - # prevents an infinite loop fixed in r27013. - def >>(n) - y, m = (year * 12 + (mon - 1) + n).divmod(12) - m, = (m + 1) .divmod(1) - d = mday - until jd2 = self.class.valid_civil?(y, m, d, start) - d -= 1 - raise ArgumentError, 'invalid date' unless d > 0 - end - self + (jd2 - jd) - end - end - class << self # Returns a new Date representing the date 1 day ago (i.e. yesterday's date). def yesterday diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb index 338104fd05..3262c254f7 100644 --- a/activesupport/lib/active_support/core_ext/date/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date/conversions.rb @@ -63,12 +63,6 @@ class Date alias_method :default_inspect, :inspect alias_method :inspect, :readable_inspect - # A method to keep Time, Date and DateTime instances interchangeable on conversions. - # In this case, it simply returns +self+. - def to_date - self - end if RUBY_VERSION < '1.9' - # Converts a Date instance to a Time, where the time is set to the beginning of the day. # The timezone can be either :local or :utc (default :local). # @@ -83,23 +77,6 @@ class Date ::Time.send("#{form}_time", year, month, day) end - # Converts a Date instance to a DateTime, where the time is set to the beginning of the day - # and UTC offset is set to 0. - # - # ==== Examples - # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 - # - # date.to_datetime # => Sat, 10 Nov 2007 00:00:00 0000 - def to_datetime - ::DateTime.civil(year, month, day, 0, 0, 0, 0) - end if RUBY_VERSION < '1.9' - - def iso8601 - strftime('%F') - end if RUBY_VERSION < '1.9' - - alias_method :rfc3339, :iso8601 if RUBY_VERSION < '1.9' - def xmlschema to_time_in_current_zone.xmlschema end diff --git a/activesupport/lib/active_support/core_ext/date/freeze.rb b/activesupport/lib/active_support/core_ext/date/freeze.rb deleted file mode 100644 index a731f8345e..0000000000 --- a/activesupport/lib/active_support/core_ext/date/freeze.rb +++ /dev/null @@ -1,33 +0,0 @@ -# Date memoizes some instance methods using metaprogramming to wrap -# the methods with one that caches the result in an instance variable. -# -# If a Date is frozen but the memoized method hasn't been called, the -# first call will result in a frozen object error since the memo -# instance variable is uninitialized. -# -# Work around by eagerly memoizing before the first freeze. -# -# Ruby 1.9 uses a preinitialized instance variable so it's unaffected. -# This hack is as close as we can get to feature detection: -if RUBY_VERSION < '1.9' - require 'date' - begin - ::Date.today.freeze.jd - rescue => frozen_object_error - if frozen_object_error.message =~ /frozen/ - class Date #:nodoc: - def freeze - unless frozen? - self.class.private_instance_methods(false).each do |m| - if m.to_s =~ /\A__\d+__\Z/ - instance_variable_set(:"@#{m}", [send(m)]) - end - end - end - - super - end - end - end - end -end diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb index 48cf1a435d..1a3cf66a1b 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -1,5 +1,3 @@ -require 'rational' unless RUBY_VERSION >= '1.9.2' - class DateTime class << self # DateTimes aren't aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zone diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb index ca899c714c..851012e3bf 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -66,7 +66,7 @@ class DateTime # Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class. # If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time. def to_time - self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec, sec_fraction * (RUBY_VERSION < '1.9' ? 86400000000 : 1000000)) : self + self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec, sec_fraction * 1000000) : self end # To be able to keep Times, Dates and DateTimes interchangeable on conversions. diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index d9856f2e84..ccd0e9692d 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -1,41 +1,4 @@ -require 'active_support/ordered_hash' - module Enumerable - # Ruby 1.8.7 introduces group_by, but the result isn't ordered. Override it. - remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9' - - # Collect an enumerable into sets, grouped by the result of a block. Useful, - # for example, for grouping records by date. - # - # Example: - # - # latest_transcripts.group_by(&:day).each do |day, transcripts| - # p "#{day} -> #{transcripts.map(&:class).join(', ')}" - # end - # "2006-03-01 -> Transcript" - # "2006-02-28 -> Transcript" - # "2006-02-27 -> Transcript, Transcript" - # "2006-02-26 -> Transcript, Transcript" - # "2006-02-25 -> Transcript" - # "2006-02-24 -> Transcript, Transcript" - # "2006-02-23 -> Transcript" - def group_by - return to_enum :group_by unless block_given? - assoc = ActiveSupport::OrderedHash.new - - each do |element| - key = yield(element) - - if assoc.has_key?(key) - assoc[key] << element - else - assoc[key] = [element] - end - end - - assoc - end unless [].respond_to?(:group_by) - # Calculates a sum from the elements. Examples: # # payments.sum { |p| p.price * p.tax_rate } diff --git a/activesupport/lib/active_support/core_ext/exception.rb b/activesupport/lib/active_support/core_ext/exception.rb index ef801e713d..ba7757ea07 100644 --- a/activesupport/lib/active_support/core_ext/exception.rb +++ b/activesupport/lib/active_support/core_ext/exception.rb @@ -1,3 +1,3 @@ module ActiveSupport - FrozenObjectError = RUBY_VERSION < '1.9' ? TypeError : RuntimeError + FrozenObjectError = RuntimeError end diff --git a/activesupport/lib/active_support/core_ext/float.rb b/activesupport/lib/active_support/core_ext/float.rb deleted file mode 100644 index 7570471b95..0000000000 --- a/activesupport/lib/active_support/core_ext/float.rb +++ /dev/null @@ -1 +0,0 @@ -require 'active_support/core_ext/float/rounding' diff --git a/activesupport/lib/active_support/core_ext/float/rounding.rb b/activesupport/lib/active_support/core_ext/float/rounding.rb deleted file mode 100644 index 0d4fb87665..0000000000 --- a/activesupport/lib/active_support/core_ext/float/rounding.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Float - alias precisionless_round round - private :precisionless_round - - # Rounds the float with the specified precision. - # - # x = 1.337 - # x.round # => 1 - # x.round(1) # => 1.3 - # x.round(2) # => 1.34 - def round(precision = nil) - if precision - magnitude = 10.0 ** precision - (self * magnitude).round / magnitude - else - precisionless_round - end - end -end if RUBY_VERSION < '1.9' diff --git a/activesupport/lib/active_support/core_ext/io.rb b/activesupport/lib/active_support/core_ext/io.rb deleted file mode 100644 index 75f1055191..0000000000 --- a/activesupport/lib/active_support/core_ext/io.rb +++ /dev/null @@ -1,15 +0,0 @@ -if RUBY_VERSION < '1.9.2' - -# :stopdoc: -class IO - def self.binread(name, length = nil, offset = nil) - return File.read name unless length || offset - File.open(name, 'rb') { |f| - f.seek offset if offset - f.read length - } - end -end -# :startdoc: - -end diff --git a/activesupport/lib/active_support/core_ext/module/introspection.rb b/activesupport/lib/active_support/core_ext/module/introspection.rb index c08ad251dd..1893a9cfa6 100644 --- a/activesupport/lib/active_support/core_ext/module/introspection.rb +++ b/activesupport/lib/active_support/core_ext/module/introspection.rb @@ -57,27 +57,8 @@ class Module parents end - if RUBY_VERSION < '1.9' - # Returns the constants that have been defined locally by this object and - # not in an ancestor. This method is exact if running under Ruby 1.9. In - # previous versions it may miss some constants if their definition in some - # ancestor is identical to their definition in the receiver. - def local_constants - inherited = {} - - ancestors.each do |anc| - next if anc == self - anc.constants.each { |const| inherited[const] = anc.const_get(const) } - end - - constants.select do |const| - !inherited.key?(const) || inherited[const].object_id != const_get(const).object_id - end - end - else - def local_constants #:nodoc: - constants(false) - end + def local_constants #:nodoc: + constants(false) end # Returns the names of the constants defined locally rather than the diff --git a/activesupport/lib/active_support/core_ext/module/qualified_const.rb b/activesupport/lib/active_support/core_ext/module/qualified_const.rb index d1a0ee2f83..8adf050b6b 100644 --- a/activesupport/lib/active_support/core_ext/module/qualified_const.rb +++ b/activesupport/lib/active_support/core_ext/module/qualified_const.rb @@ -23,26 +23,14 @@ end # Object.const_get("::String") raises NameError and so does qualified_const_get. #++ class Module - if method(:const_defined?).arity == 1 - def qualified_const_defined?(path) - QualifiedConstUtils.raise_if_absolute(path) - - QualifiedConstUtils.names(path).inject(self) do |mod, name| - return unless mod.const_defined?(name) - mod.const_get(name) - end - return true - end - else - def qualified_const_defined?(path, search_parents=true) - QualifiedConstUtils.raise_if_absolute(path) + def qualified_const_defined?(path, search_parents=true) + QualifiedConstUtils.raise_if_absolute(path) - QualifiedConstUtils.names(path).inject(self) do |mod, name| - return unless mod.const_defined?(name, search_parents) - mod.const_get(name) - end - return true + QualifiedConstUtils.names(path).inject(self) do |mod, name| + return unless mod.const_defined?(name, search_parents) + mod.const_get(name) end + return true end def qualified_const_get(path) diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb index fe27f45295..7271671908 100644 --- a/activesupport/lib/active_support/core_ext/object/blank.rb +++ b/activesupport/lib/active_support/core_ext/object/blank.rb @@ -89,9 +89,6 @@ class Hash end class String - # 0x3000: fullwidth whitespace - NON_WHITESPACE_REGEXP = %r![^\s#{[0x3000].pack("U")}]! - # A string is blank if it's empty or contains whitespaces only: # # "".blank? # => true @@ -100,12 +97,7 @@ class String # " something here ".blank? # => false # def blank? - # 1.8 does not takes [:space:] properly - if encoding_aware? - self !~ /[^[:space:]]/ - else - self !~ NON_WHITESPACE_REGEXP - end + self !~ /[^[:space:]]/ end end diff --git a/activesupport/lib/active_support/core_ext/object/instance_variables.rb b/activesupport/lib/active_support/core_ext/object/instance_variables.rb index eda9694614..66caf9bec8 100644 --- a/activesupport/lib/active_support/core_ext/object/instance_variables.rb +++ b/activesupport/lib/active_support/core_ext/object/instance_variables.rb @@ -23,11 +23,7 @@ class Object # end # # C.new(0, 1).instance_variable_names # => ["@y", "@x"] - if RUBY_VERSION >= '1.9' - def instance_variable_names - instance_variables.map { |var| var.to_s } - end - else - alias_method :instance_variable_names, :instance_variables + def instance_variable_names + instance_variables.map { |var| var.to_s } end end diff --git a/activesupport/lib/active_support/core_ext/range.rb b/activesupport/lib/active_support/core_ext/range.rb index 2428a02242..c0736f3a44 100644 --- a/activesupport/lib/active_support/core_ext/range.rb +++ b/activesupport/lib/active_support/core_ext/range.rb @@ -2,4 +2,3 @@ require 'active_support/core_ext/range/blockless_step' require 'active_support/core_ext/range/conversions' require 'active_support/core_ext/range/include_range' require 'active_support/core_ext/range/overlaps' -require 'active_support/core_ext/range/cover' diff --git a/activesupport/lib/active_support/core_ext/range/cover.rb b/activesupport/lib/active_support/core_ext/range/cover.rb deleted file mode 100644 index 3a182cddd2..0000000000 --- a/activesupport/lib/active_support/core_ext/range/cover.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Range - alias_method(:cover?, :include?) unless instance_methods.include?(:cover?) -end diff --git a/activesupport/lib/active_support/core_ext/string/conversions.rb b/activesupport/lib/active_support/core_ext/string/conversions.rb index 0f8933b658..73eedf5982 100644 --- a/activesupport/lib/active_support/core_ext/string/conversions.rb +++ b/activesupport/lib/active_support/core_ext/string/conversions.rb @@ -1,37 +1,8 @@ -# encoding: utf-8 require 'date' require 'active_support/core_ext/time/publicize_conversion_methods' require 'active_support/core_ext/time/calculations' class String - # Returns the codepoint of the first character of the string, assuming a - # single-byte character encoding: - # - # "a".ord # => 97 - # "à".ord # => 224, in ISO-8859-1 - # - # This method is defined in Ruby 1.8 for Ruby 1.9 forward compatibility on - # these character encodings. - # - # <tt>ActiveSupport::Multibyte::Chars#ord</tt> is forward compatible with - # Ruby 1.9 on UTF8 strings: - # - # "a".mb_chars.ord # => 97 - # "à".mb_chars.ord # => 224, in UTF8 - # - # Note that the 224 is different in both examples. In ISO-8859-1 "à" is - # represented as a single byte, 224. In UTF8 it is represented with two - # bytes, namely 195 and 160, but its Unicode codepoint is 224. If we - # call +ord+ on the UTF8 string "à" the return value will be 195. That is - # not an error, because UTF8 is unsupported, the call itself would be - # bogus. - def ord - self[0] - end unless method_defined?(:ord) - - # +getbyte+ backport from Ruby 1.9 - alias_method :getbyte, :[] unless method_defined?(:getbyte) - # Form can be either :utc (default) or :local. def to_time(form = :utc) return nil if self.blank? diff --git a/activesupport/lib/active_support/core_ext/string/encoding.rb b/activesupport/lib/active_support/core_ext/string/encoding.rb index d4781bfe0c..236f72e933 100644 --- a/activesupport/lib/active_support/core_ext/string/encoding.rb +++ b/activesupport/lib/active_support/core_ext/string/encoding.rb @@ -1,11 +1,5 @@ class String - if defined?(Encoding) && "".respond_to?(:encode) - def encoding_aware? - true - end - else - def encoding_aware? - false - end + def encoding_aware? + true end end
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb index 400db2ce39..4e7824ad74 100644 --- a/activesupport/lib/active_support/core_ext/string/multibyte.rb +++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb @@ -2,71 +2,55 @@ require 'active_support/multibyte' class String - if RUBY_VERSION >= "1.9" - # == Multibyte proxy - # - # +mb_chars+ is a multibyte safe proxy for string methods. - # - # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which - # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy - # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string. - # - # name = 'Claus Müller' - # name.reverse # => "rell??M sualC" - # name.length # => 13 - # - # 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. - # - # == Method chaining - # - # 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 - # - # == Interoperability and configuration - # - # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between - # String and Char work like expected. The bang! methods change the internal string representation in the Chars - # 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 behavior see ActiveSupport::Multibyte. - def mb_chars - if ActiveSupport::Multibyte.proxy_class.consumes?(self) - ActiveSupport::Multibyte.proxy_class.new(self) - else - self - end - end - - def is_utf8? - case encoding - when Encoding::UTF_8 - valid_encoding? - when Encoding::ASCII_8BIT, Encoding::US_ASCII - dup.force_encoding(Encoding::UTF_8).valid_encoding? - else - false - end - end - else - def mb_chars - if ActiveSupport::Multibyte.proxy_class.wants?(self) - ActiveSupport::Multibyte.proxy_class.new(self) - else - self - end + # == Multibyte proxy + # + # +mb_chars+ is a multibyte safe proxy for string methods. + # + # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which + # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy + # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string. + # + # name = 'Claus Müller' + # name.reverse # => "rell??M sualC" + # name.length # => 13 + # + # 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. + # + # == Method chaining + # + # 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 + # + # == Interoperability and configuration + # + # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between + # String and Char work like expected. The bang! methods change the internal string representation in the Chars + # 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 behavior see ActiveSupport::Multibyte. + def mb_chars + if ActiveSupport::Multibyte.proxy_class.consumes?(self) + ActiveSupport::Multibyte.proxy_class.new(self) + else + self end + end - # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have - # them), returns false otherwise. - def is_utf8? - ActiveSupport::Multibyte::Chars.consumes?(self) + def is_utf8? + case encoding + when Encoding::UTF_8 + valid_encoding? + when Encoding::ASCII_8BIT, Encoding::US_ASCII + dup.force_encoding(Encoding::UTF_8).valid_encoding? + else + false end end end diff --git a/activesupport/lib/active_support/core_ext/uri.rb b/activesupport/lib/active_support/core_ext/uri.rb index ee991e3439..0b219ce44a 100644 --- a/activesupport/lib/active_support/core_ext/uri.rb +++ b/activesupport/lib/active_support/core_ext/uri.rb @@ -1,22 +1,18 @@ # encoding: utf-8 -if RUBY_VERSION >= '1.9' - require 'uri' +require 'uri' +str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese. +parser = URI::Parser.new - str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese. - - parser = URI::Parser.new - - unless str == parser.unescape(parser.escape(str)) - URI::Parser.class_eval do - remove_method :unescape - def unescape(str, escaped = /%[a-fA-F\d]{2}/) - # TODO: Are we actually sure that ASCII == UTF-8? - # YK: My initial experiments say yes, but let's be sure please - enc = str.encoding - enc = Encoding::UTF_8 if enc == Encoding::US_ASCII - str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc) - end +unless str == parser.unescape(parser.escape(str)) + URI::Parser.class_eval do + remove_method :unescape + def unescape(str, escaped = /%[a-fA-F\d]{2}/) + # TODO: Are we actually sure that ASCII == UTF-8? + # YK: My initial experiments say yes, but let's be sure please + enc = str.encoding + enc = Encoding::UTF_8 if enc == Encoding::US_ASCII + str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc) end end end diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 43dd22654a..e121e452a3 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -369,26 +369,12 @@ module ActiveSupport #:nodoc: end # Is the provided constant path defined? - if Module.method(:const_defined?).arity == 1 - def qualified_const_defined?(path) - Object.qualified_const_defined?(path.sub(/^::/, '')) - end - else - def qualified_const_defined?(path) - Object.qualified_const_defined?(path.sub(/^::/, ''), false) - end + def qualified_const_defined?(path) + Object.qualified_const_defined?(path.sub(/^::/, ''), false) end - if Module.method(:const_defined?).arity == 1 - # Does this module define this constant? - # Wrapper to accommodate changing Module#const_defined? in Ruby 1.9 - def local_const_defined?(mod, const) - mod.const_defined?(const) - end - else - def local_const_defined?(mod, const) #:nodoc: - mod.const_defined?(const, false) - end + def local_const_defined?(mod, const) #:nodoc: + mod.const_defined?(const, false) end # Given +path+, a filesystem path to a ruby file, return an array of constant diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index b78d92f599..ba35b515f2 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -38,16 +38,10 @@ module ActiveSupport #:nodoc: alias to_s wrapped_string alias to_str wrapped_string - if RUBY_VERSION >= "1.9" - # Creates a new Chars instance by wrapping _string_. - def initialize(string) - @wrapped_string = string - @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen? - end - else - def initialize(string) #:nodoc: - @wrapped_string = string - end + # Creates a new Chars instance by wrapping _string_. + def initialize(string) + @wrapped_string = string + @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen? end # Forward all undefined methods to the wrapped string. @@ -94,151 +88,8 @@ module ActiveSupport #:nodoc: @wrapped_string <=> other.to_s end - if RUBY_VERSION < "1.9" - # Returns +true+ if the Chars class can and should act as a proxy for the string _string_. Returns - # +false+ otherwise. - def self.wants?(string) - $KCODE == 'UTF8' && consumes?(string) - end - - # 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" - def +(other) - chars(@wrapped_string + other) - end - - # 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 - def =~(other) - translate_offset(@wrapped_string =~ other) - end - - # Inserts the passed string at specified codepoint offsets. - # - # Example: - # '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 - @wrapped_string.replace( - Unicode.u_unpack(@wrapped_string).insert(offset, *Unicode.u_unpack(fragment)).pack('U*') - ) - else - raise IndexError, "index #{offset} out of string" - end - self - end - - # Returns +true+ if contained string contains _other_. Returns +false+ otherwise. - # - # Example: - # 'Café'.mb_chars.include?('é') # => true - def include?(other) - # We have to redefine this method because Enumerable defines it. - @wrapped_string.include?(other) - end - - # 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 - def index(needle, offset=0) - wrapped_offset = first(offset).wrapped_string.length - index = @wrapped_string.index(needle, wrapped_offset) - index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil - end - - # Returns the position _needle_ in the string, counting in - # codepoints, searching backward from _offset_ or the end of the - # 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 - def rindex(needle, offset=nil) - offset ||= length - wrapped_offset = first(offset).wrapped_string.length - index = @wrapped_string.rindex(needle, wrapped_offset) - index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil - end - - # Returns the number of codepoints in the string - def size - Unicode.u_unpack(@wrapped_string).size - end - alias_method :length, :size - - # Strips entire range of Unicode whitespace from the right of the string. - def rstrip - chars(@wrapped_string.gsub(Unicode::TRAILERS_PAT, '')) - end - - # Strips entire range of Unicode whitespace from the left of the string. - def lstrip - chars(@wrapped_string.gsub(Unicode::LEADERS_PAT, '')) - end - - # Strips entire range of Unicode whitespace from the right and left of the string. - def strip - rstrip.lstrip - end - - # Returns the codepoint of the first character in the string. - # - # Example: - # 'こんにちは'.mb_chars.ord # => 12371 - def ord - Unicode.u_unpack(@wrapped_string)[0] - end - - # Works just like <tt>String#rjust</tt>, only integer specifies characters instead of bytes. - # - # Example: - # - # "¾ cup".mb_chars.rjust(8).to_s - # # => " ¾ cup" - # - # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace - # # => " ¾ cup" - def rjust(integer, padstr=' ') - justify(integer, :right, padstr) - end - - # Works just like <tt>String#ljust</tt>, only integer specifies characters instead of bytes. - # - # Example: - # - # "¾ cup".mb_chars.rjust(8).to_s - # # => "¾ cup " - # - # "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace - # # => "¾ cup " - def ljust(integer, padstr=' ') - justify(integer, :left, padstr) - end - - # Works just like <tt>String#center</tt>, only integer specifies characters instead of bytes. - # - # Example: - # - # "¾ cup".mb_chars.center(8).to_s - # # => " ¾ cup " - # - # "¾ cup".mb_chars.center(8, " ").to_s # Use non-breaking whitespace - # # => " ¾ cup " - def center(integer, padstr=' ') - justify(integer, :center, padstr) - end - - else - def =~(other) - @wrapped_string =~ other - end + def =~(other) + @wrapped_string =~ other end # Works just like <tt>String#split</tt>, with the exception that the items in the resulting list are Chars diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index b0d4f2bd86..d4f309fbd7 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -51,172 +51,5 @@ module ActiveSupport def extractable_options? true end - - # Hash is ordered in Ruby 1.9! - if RUBY_VERSION < '1.9' - - # In MRI the Hash class is core and written in C. In particular, methods are - # programmed with explicit C function calls and polymorphism is not honored. - # - # For example, []= is crucial in this implementation to maintain the @keys - # array but hash.c invokes rb_hash_aset() originally. This prevents method - # reuse through inheritance and forces us to reimplement stuff. - # - # For instance, we cannot use the inherited #merge! because albeit the algorithm - # itself would work, our []= is not being called at all by the C code. - - def initialize(*args, &block) - super - @keys = [] - end - - def self.[](*args) - ordered_hash = new - - if (args.length == 1 && args.first.is_a?(Array)) - args.first.each do |key_value_pair| - next unless (key_value_pair.is_a?(Array)) - ordered_hash[key_value_pair[0]] = key_value_pair[1] - end - - return ordered_hash - end - - unless (args.size % 2 == 0) - raise ArgumentError.new("odd number of arguments for Hash") - end - - args.each_with_index do |val, ind| - next if (ind % 2 != 0) - ordered_hash[val] = args[ind + 1] - end - - ordered_hash - end - - def initialize_copy(other) - super - # make a deep copy of keys - @keys = other.keys - end - - def []=(key, value) - @keys << key unless has_key?(key) - super - end - - def delete(key) - if has_key? key - index = @keys.index(key) - @keys.delete_at index - end - super - end - - def delete_if - super - sync_keys! - self - end - - def reject! - super - sync_keys! - self - end - - def reject(&block) - dup.reject!(&block) - end - - def keys - @keys.dup - end - - def values - @keys.collect { |key| self[key] } - end - - def to_hash - self - end - - def to_a - @keys.map { |key| [ key, self[key] ] } - end - - def each_key - return to_enum(:each_key) unless block_given? - @keys.each { |key| yield key } - self - end - - def each_value - return to_enum(:each_value) unless block_given? - @keys.each { |key| yield self[key]} - self - end - - def each - return to_enum(:each) unless block_given? - @keys.each {|key| yield [key, self[key]]} - self - end - - def each_pair - return to_enum(:each_pair) unless block_given? - @keys.each {|key| yield key, self[key]} - self - end - - alias_method :select, :find_all - - def clear - super - @keys.clear - self - end - - def shift - k = @keys.first - v = delete(k) - [k, v] - end - - def merge!(other_hash) - if block_given? - other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v } - else - other_hash.each { |k, v| self[k] = v } - end - self - end - - alias_method :update, :merge! - - def merge(other_hash, &block) - dup.merge!(other_hash, &block) - end - - # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not. - def replace(other) - super - @keys = other.keys - self - end - - def invert - OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}] - end - - def inspect - "#<OrderedHash #{super}>" - end - - private - def sync_keys! - @keys.delete_if {|k| !has_key?(k)} - end - end end end diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb index f3629ada5b..4e1a58a801 100644 --- a/activesupport/lib/active_support/testing/assertions.rb +++ b/activesupport/lib/active_support/testing/assertions.rb @@ -87,7 +87,7 @@ module ActiveSupport # Test if an expression is not blank. Passes if object.present? is true. # - # assert_present {:data => 'x' } # => true + # assert_present({:data => 'x' }) # => true def assert_present(object, message=nil) message ||= "#{object.inspect} is blank" assert object.present?, message diff --git a/activesupport/lib/active_support/testing/performance/ruby.rb b/activesupport/lib/active_support/testing/performance/ruby.rb index 7d6d047ef6..26731c6bd7 100644 --- a/activesupport/lib/active_support/testing/performance/ruby.rb +++ b/activesupport/lib/active_support/testing/performance/ruby.rb @@ -144,8 +144,6 @@ end if RUBY_VERSION.between?('1.9.2', '2.0') require 'active_support/testing/performance/ruby/yarv' -elsif RUBY_VERSION.between?('1.8.6', '1.9') - require 'active_support/testing/performance/ruby/mri' else $stderr.puts 'Update your ruby interpreter to be able to run benchmarks.' exit diff --git a/activesupport/lib/active_support/testing/performance/ruby/mri.rb b/activesupport/lib/active_support/testing/performance/ruby/mri.rb deleted file mode 100644 index 142279dd6e..0000000000 --- a/activesupport/lib/active_support/testing/performance/ruby/mri.rb +++ /dev/null @@ -1,57 +0,0 @@ -module ActiveSupport - module Testing - module Performance - module Metrics - class Base - protected - # Ruby 1.8 + ruby-prof wrapper (enable/disable stats for Benchmarker) - if GC.respond_to?(:enable_stats) - def with_gc_stats - GC.enable_stats - GC.start - yield - ensure - GC.disable_stats - end - end - end - - class Memory < DigitalInformationUnit - # Ruby 1.8 + ruby-prof wrapper - if RubyProf.respond_to?(:measure_memory) - def measure - RubyProf.measure_memory - end - end - end - - class Objects < Amount - # Ruby 1.8 + ruby-prof wrapper - if RubyProf.respond_to?(:measure_allocations) - def measure - RubyProf.measure_allocations - end - end - end - - class GcRuns < Amount - # Ruby 1.8 + ruby-prof wrapper - if RubyProf.respond_to?(:measure_gc_runs) - def measure - RubyProf.measure_gc_runs - end - end - end - - class GcTime < Time - # Ruby 1.8 + ruby-prof wrapper - if RubyProf.respond_to?(:measure_gc_time) - def measure - RubyProf.measure_gc_time / 1000.0 / 1000.0 - end - end - end - end - end - end -end diff --git a/activesupport/lib/active_support/time.rb b/activesupport/lib/active_support/time.rb index 86f057d676..4ef289a414 100644 --- a/activesupport/lib/active_support/time.rb +++ b/activesupport/lib/active_support/time.rb @@ -21,7 +21,6 @@ require 'active_support/core_ext/time/conversions' require 'active_support/core_ext/time/zones' require 'active_support/core_ext/date/acts_like' -require 'active_support/core_ext/date/freeze' require 'active_support/core_ext/date/calculations' require 'active_support/core_ext/date/conversions' require 'active_support/core_ext/date/zones' diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index 0382739871..504ac3e9b9 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -11,15 +11,11 @@ lib = File.expand_path("#{File.dirname(__FILE__)}/../lib") $:.unshift(lib) unless $:.include?('lib') || $:.include?(lib) require 'active_support/core_ext/kernel/reporting' - require 'active_support/core_ext/string/encoding' -if "ruby".encoding_aware? - # These are the normal settings that will be set up by Railties - # TODO: Have these tests support other combinations of these values - silence_warnings do - Encoding.default_internal = "UTF-8" - Encoding.default_external = "UTF-8" - end + +silence_warnings do + Encoding.default_internal = "UTF-8" + Encoding.default_external = "UTF-8" end require 'test/unit' @@ -30,9 +26,6 @@ silence_warnings { require 'mocha' } ENV['NO_RELOAD'] = '1' require 'active_support' -# Include shims until we get off 1.8.6 -require 'active_support/ruby/shim' if RUBY_VERSION < '1.8.7' - def uses_memcached(test_name) require 'memcache' begin @@ -43,22 +36,5 @@ def uses_memcached(test_name) end end -def with_kcode(code) - if RUBY_VERSION < '1.9' - begin - old_kcode, $KCODE = $KCODE, code - yield - ensure - $KCODE = old_kcode - end - else - yield - end -end - # Show backtraces for deprecated behavior for quicker cleanup. -ActiveSupport::Deprecation.debug = true - -if RUBY_VERSION < '1.9' - $KCODE = 'UTF8' -end +ActiveSupport::Deprecation.debug = true
\ No newline at end of file diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index c040d86327..09d4765390 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -384,16 +384,6 @@ class DateExtCalculationsTest < ActiveSupport::TestCase end end - if RUBY_VERSION < '1.9' - def test_rfc3339 - assert_equal('1980-02-28', Date.new(1980, 2, 28).rfc3339) - end - - def test_iso8601 - assert_equal('1980-02-28', Date.new(1980, 2, 28).iso8601) - end - end - def test_today Date.stubs(:current).returns(Date.new(2000, 1, 1)) assert_equal false, Date.new(1999, 12, 31).today? diff --git a/activesupport/test/core_ext/float_ext_test.rb b/activesupport/test/core_ext/float_ext_test.rb deleted file mode 100644 index ac7e7a8ed6..0000000000 --- a/activesupport/test/core_ext/float_ext_test.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'abstract_unit' -require 'active_support/core_ext/float/rounding' - -class FloatExtRoundingTests < Test::Unit::TestCase - def test_round_for_positive_number - assert_equal 1, 1.4.round - assert_equal 2, 1.6.round - assert_equal 2, 1.6.round(0) - assert_equal 1.4, 1.4.round(1) - assert_equal 1.4, 1.4.round(3) - assert_equal 1.5, 1.45.round(1) - assert_equal 1.45, 1.445.round(2) - end - - def test_round_for_negative_number - assert_equal( -1, -1.4.round ) - assert_equal( -2, -1.6.round ) - assert_equal( -1.4, -1.4.round(1) ) - assert_equal( -1.5, -1.45.round(1) ) - end - - def test_round_with_negative_precision - assert_equal 123460.0, 123456.0.round(-1) - assert_equal 123500.0, 123456.0.round(-2) - end -end diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index eb8ed761da..dfa0cdb478 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -27,11 +27,7 @@ class HashExtTest < Test::Unit::TestCase @symbols = { :a => 1, :b => 2 } @mixed = { :a => 1, 'b' => 2 } @fixnums = { 0 => 1, 1 => 2 } - if RUBY_VERSION < '1.9.0' - @illegal_symbols = { "\0" => 1, "" => 2, [] => 3 } - else - @illegal_symbols = { [] => 3 } - end + @illegal_symbols = { [] => 3 } end def test_methods diff --git a/activesupport/test/core_ext/io_test.rb b/activesupport/test/core_ext/io_test.rb deleted file mode 100644 index b9abf685da..0000000000 --- a/activesupport/test/core_ext/io_test.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'abstract_unit' - -require 'active_support/core_ext/io' - -class IOTest < Test::Unit::TestCase - def test_binread_one_arg - assert_equal File.read(__FILE__), IO.binread(__FILE__) - end - - def test_binread_two_args - assert_equal File.read(__FILE__).bytes.first(10).pack('C*'), - IO.binread(__FILE__, 10) - end - - def test_binread_three_args - actual = IO.binread(__FILE__, 5, 10) - expected = File.open(__FILE__, 'rb') { |f| - f.seek 10 - f.read 5 - } - assert_equal expected, actual - end -end diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb index 1424fa4aca..f4b773e5fb 100644 --- a/activesupport/test/core_ext/range_ext_test.rb +++ b/activesupport/test/core_ext/range_ext_test.rb @@ -63,15 +63,8 @@ class RangeTest < Test::Unit::TestCase assert_equal [1,3,5,7,9], array end - if RUBY_VERSION < '1.9' - def test_cover - assert((1..3).cover?(2)) - assert !(1..3).cover?(4) - end - else - def test_cover_is_not_override - range = (1..3) - assert range.method(:include?) != range.method(:cover?) - end + def test_cover_is_not_override + range = (1..3) + assert range.method(:include?) != range.method(:cover?) end end diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 47b9f68ed0..aeae2579b4 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -160,14 +160,6 @@ class StringInflectionsTest < Test::Unit::TestCase assert_equal 97, 'abc'.ord end - if RUBY_VERSION < '1.9' - def test_getbyte - assert_equal 97, 'a'.getbyte(0) - assert_equal 99, 'abc'.getbyte(2) - assert_nil 'abc'.getbyte(3) - end - end - def test_string_to_time assert_equal Time.utc(2005, 2, 27, 23, 50), "2005-02-27 23:50".to_time assert_equal Time.local(2005, 2, 27, 23, 50), "2005-02-27 23:50".to_time(:local) @@ -287,21 +279,9 @@ class StringInflectionsTest < Test::Unit::TestCase assert_equal "Hello Big[...]", "Hello Big World!".truncate(15, :omission => "[...]", :separator => ' ') end - if RUBY_VERSION < '1.9.0' - def test_truncate_multibyte - with_kcode 'none' do - assert_equal "\354\225\210\353\205\225\355...", "\354\225\210\353\205\225\355\225\230\354\204\270\354\232\224".truncate(10) - end - with_kcode 'u' do - assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...", - "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".truncate(10) - end - end - else - def test_truncate_multibyte - assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8'), - "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8').truncate(10) - end + def test_truncate_multibyte + assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8'), + "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8').truncate(10) end def test_constantize @@ -338,22 +318,8 @@ class CoreExtStringMultibyteTest < ActiveSupport::TestCase assert !BYTE_STRING.is_utf8? end - if RUBY_VERSION < '1.9' - def test_mb_chars_returns_self_when_kcode_not_set - with_kcode('none') do - assert_kind_of String, UNICODE_STRING.mb_chars - end - end - - def test_mb_chars_returns_an_instance_of_the_chars_proxy_when_kcode_utf8 - with_kcode('UTF8') do - assert_kind_of ActiveSupport::Multibyte.proxy_class, UNICODE_STRING.mb_chars - end - end - else - def test_mb_chars_returns_instance_of_proxy_class - assert_kind_of ActiveSupport::Multibyte.proxy_class, UNICODE_STRING.mb_chars - end + def test_mb_chars_returns_instance_of_proxy_class + assert_kind_of ActiveSupport::Multibyte.proxy_class, UNICODE_STRING.mb_chars end end @@ -479,11 +445,7 @@ class OutputSafetyTest < ActiveSupport::TestCase end test 'knows whether it is encoding aware' do - if RUBY_VERSION >= "1.9" - assert 'ruby'.encoding_aware? - else - assert !'ruby'.encoding_aware? - end + assert 'ruby'.encoding_aware? end test "call to_param returns a normal string" do diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index 9d9e411c28..04f5ea85a8 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -448,9 +448,8 @@ class TimeWithZoneTest < Test::Unit::TestCase end def test_ruby_19_weekday_name_query_methods - ruby_19_or_greater = RUBY_VERSION >= '1.9' %w(sunday? monday? tuesday? wednesday? thursday? friday? saturday?).each do |name| - assert_equal ruby_19_or_greater, @twz.respond_to?(name) + assert_respond_to @twz, name end end diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index 8cf1a54a99..ad9a497515 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -88,25 +88,21 @@ class TestJSONEncoding < Test::Unit::TestCase assert_equal %({\"a\":\"b\",\"c\":\"d\"}), sorted_json(ActiveSupport::JSON.encode(:a => :b, :c => :d)) end - def test_utf8_string_encoded_properly_when_kcode_is_utf8 - with_kcode 'UTF8' do - result = ActiveSupport::JSON.encode('€2.99') - assert_equal '"\\u20ac2.99"', result - assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding) - - result = ActiveSupport::JSON.encode('✎☺') - assert_equal '"\\u270e\\u263a"', result - assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding) - end + def test_utf8_string_encoded_properly + result = ActiveSupport::JSON.encode('€2.99') + assert_equal '"\\u20ac2.99"', result + assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding) + + result = ActiveSupport::JSON.encode('✎☺') + assert_equal '"\\u270e\\u263a"', result + assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding) end - if '1.9'.respond_to?(:force_encoding) - def test_non_utf8_string_transcodes - s = '二'.encode('Shift_JIS') - result = ActiveSupport::JSON.encode(s) - assert_equal '"\\u4e8c"', result - assert_equal Encoding::UTF_8, result.encoding - end + def test_non_utf8_string_transcodes + s = '二'.encode('Shift_JIS') + result = ActiveSupport::JSON.encode(s) + assert_equal '"\\u4e8c"', result + assert_equal Encoding::UTF_8, result.encoding end def test_exception_raised_when_encoding_circular_reference_in_array diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index bfff10fff2..20e56e2c81 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -101,15 +101,8 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase def setup @chars = UNICODE_STRING.dup.mb_chars - - if RUBY_VERSION < '1.9' - # Multibyte support all kinds of whitespace (ie. NEWLINE, SPACE, EM SPACE) - @whitespace = "\n\t#{[32, 8195].pack('U*')}" - else - # Ruby 1.9 only supports basic whitespace - @whitespace = "\n\t " - end - + # Ruby 1.9 only supports basic whitespace + @whitespace = "\n\t " @byte_order_mark = [65279].pack('U') end @@ -150,10 +143,8 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase assert_not_equal original, proxy.to_s end - if RUBY_VERSION >= '1.9' - def test_unicode_string_should_have_utf8_encoding - assert_equal Encoding::UTF_8, UNICODE_STRING.encoding - end + def test_unicode_string_should_have_utf8_encoding + assert_equal Encoding::UTF_8, UNICODE_STRING.encoding end def test_identity diff --git a/activesupport/test/multibyte_utils_test.rb b/activesupport/test/multibyte_utils_test.rb index 0a2f20d282..f807492be0 100644 --- a/activesupport/test/multibyte_utils_test.rb +++ b/activesupport/test/multibyte_utils_test.rb @@ -56,37 +56,9 @@ class MultibyteUtilsTest < ActiveSupport::TestCase end end - if RUBY_VERSION < '1.9' - test "clean leaves ASCII strings intact" do - with_encoding('None') do - [ - 'word', "\270\236\010\210\245" - ].each do |string| - assert_equal string, ActiveSupport::Multibyte.clean(string) - end - end - end - - test "clean cleans invalid characters from UTF-8 encoded strings" do - with_encoding('UTF8') do - cleaned_utf8 = [8].pack('C*') - assert_equal example('valid UTF-8'), ActiveSupport::Multibyte.clean(example('valid UTF-8')) - assert_equal cleaned_utf8, ActiveSupport::Multibyte.clean(example('invalid UTF-8')) - end - end - - test "clean cleans invalid characters from Shift-JIS encoded strings" do - with_encoding('SJIS') do - cleaned_sjis = [184, 0, 136, 165].pack('C*') - assert_equal example('valid Shift-JIS'), ActiveSupport::Multibyte.clean(example('valid Shift-JIS')) - assert_equal cleaned_sjis, ActiveSupport::Multibyte.clean(example('invalid Shift-JIS')) - end - end - else - test "clean is a no-op" do - with_encoding('UTF8') do - assert_equal example('invalid Shift-JIS'), ActiveSupport::Multibyte.clean(example('invalid Shift-JIS')) - end + test "clean is a no-op" do + with_encoding('UTF8') do + assert_equal example('invalid Shift-JIS'), ActiveSupport::Multibyte.clean(example('invalid Shift-JIS')) end end @@ -101,37 +73,21 @@ class MultibyteUtilsTest < ActiveSupport::TestCase 'invalid Shift-JIS' => [184, 158, 8, 0, 255, 136, 165].pack('C*') } - if Kernel.const_defined?(:Encoding) - def example(key) - STRINGS[key].force_encoding(Encoding.default_external) - end - - def examples - STRINGS.values.map { |s| s.force_encoding(Encoding.default_external) } - end - else - def example(key) - STRINGS[key] - end - - def examples - STRINGS.values - end + def example(key) + STRINGS[key].force_encoding(Encoding.default_external) end - if 'string'.respond_to?(:encoding) - KCODE_TO_ENCODING = Hash.new(Encoding::BINARY). - update('UTF8' => Encoding::UTF_8, 'SJIS' => Encoding::Shift_JIS) - - def with_encoding(enc) - before = Encoding.default_external - silence_warnings { Encoding.default_external = KCODE_TO_ENCODING[enc] } + def examples + STRINGS.values.map { |s| s.force_encoding(Encoding.default_external) } + end - yield + KCODE_TO_ENCODING = Hash.new(Encoding::BINARY). + update('UTF8' => Encoding::UTF_8, 'SJIS' => Encoding::Shift_JIS) - silence_warnings { Encoding.default_external = before } - end - else - alias with_encoding with_kcode + def with_encoding(enc) + before = Encoding.default_external + silence_warnings { Encoding.default_external = KCODE_TO_ENCODING[enc] } + yield + silence_warnings { Encoding.default_external = before } end end diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index 0b5f912dc4..8119b36491 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -81,24 +81,21 @@ class OrderedHashTest < Test::Unit::TestCase keys = [] assert_equal @ordered_hash, @ordered_hash.each_key { |k| keys << k } assert_equal @keys, keys - expected_class = RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator - assert_kind_of expected_class, @ordered_hash.each_key + assert_kind_of Enumerator, @ordered_hash.each_key end def test_each_value values = [] assert_equal @ordered_hash, @ordered_hash.each_value { |v| values << v } assert_equal @values, values - expected_class = RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator - assert_kind_of expected_class, @ordered_hash.each_value + assert_kind_of Enumerator, @ordered_hash.each_value end def test_each values = [] assert_equal @ordered_hash, @ordered_hash.each {|key, value| values << value} assert_equal @values, values - expected_class = RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator - assert_kind_of expected_class, @ordered_hash.each + assert_kind_of Enumerator, @ordered_hash.each end def test_each_with_index @@ -114,9 +111,7 @@ class OrderedHashTest < Test::Unit::TestCase end assert_equal @values, values assert_equal @keys, keys - - expected_class = RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator - assert_kind_of expected_class, @ordered_hash.each_pair + assert_kind_of Enumerator, @ordered_hash.each_pair end def test_find_all diff --git a/rails.gemspec b/rails.gemspec index 3377b4e175..1d4c6c36c8 100644 --- a/rails.gemspec +++ b/rails.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| s.summary = 'Full-stack web application framework.' s.description = 'Ruby on Rails is a full-stack web framework optimized for programmer happiness and sustainable productivity. It encourages beautiful code by favoring convention over configuration.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.required_rubygems_version = ">= 1.3.6" s.author = 'David Heinemeier Hansson' diff --git a/railties/guides/rails_guides/levenshtein.rb b/railties/guides/rails_guides/levenshtein.rb index f99c6e6ba8..489aa3ea7a 100644 --- a/railties/guides/rails_guides/levenshtein.rb +++ b/railties/guides/rails_guides/levenshtein.rb @@ -1,6 +1,6 @@ module RailsGuides module Levenshtein - # Based on the pseudocode in http://en.wikipedia.org/wiki/Levenshtein_distance. + # Based on the pseudocode in http://en.wikipedia.org/wiki/Levenshtein_distance def self.distance(s1, s2) s = s1.unpack('U*') t = s2.unpack('U*') diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 6646e9cd05..0296e27725 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1974,18 +1974,6 @@ The method +ordinalize+ returns the ordinal string corresponding to the receiver NOTE: Defined in +active_support/core_ext/integer/inflections.rb+. -h3. Extensions to +Float+ - -h4. +round+ - -The built-in method +Float#round+ rounds a float to the nearest integer. In Ruby 1.9 this method takes an optional argument to let you specify a precision. Active Support adds that functionality to +round+ in previous versions of Ruby: - -<ruby> -Math::E.round(4) # => 2.7183 -</ruby> - -NOTE: Defined in +active_support/core_ext/float/rounding.rb+. - h3. Extensions to +BigDecimal+ ... diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 774c6a792e..54f3c74695 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -41,9 +41,6 @@ internet for learning Ruby, including: * "Programming Ruby":http://www.ruby-doc.org/docs/ProgrammingRuby/ * "Why's (Poignant) Guide to Ruby":http://mislav.uniqpath.com/poignant-guide/ -Also, the example code for this guide is available in the rails github:https://github.com/rails/rails repository -in rails/railties/guides/code/getting_started. - h3. What is Rails? TIP: This section goes into the background and philosophy of the Rails framework diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile index 92356edf90..66160f8b26 100644 --- a/railties/guides/source/migrations.textile +++ b/railties/guides/source/migrations.textile @@ -814,7 +814,7 @@ replaying the entire migration history. It is much simpler and faster to just load into the database a description of the current schema. For example, this is how the test database is created: the current development -database is dumped (either to +db/schema.rb+ or +db/development.sql+) and then +database is dumped (either to +db/schema.rb+ or +db/structure.sql+) and then loaded into the test database. Schema files are also useful if you want a quick look at what attributes an diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index 04c7415f3f..658756ad51 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -12,19 +12,10 @@ require 'rails/version' require 'active_support/railtie' require 'action_dispatch/railtie' -# For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the -# multibyte safe operations. Plugin authors supporting other encodings -# should override this behavior and set the relevant +default_charset+ -# on ActionController::Base. -# # For Ruby 1.9, UTF-8 is the default internal and external encoding. -if RUBY_VERSION < '1.9' - $KCODE='u' -else - silence_warnings do - Encoding.default_external = Encoding::UTF_8 - Encoding.default_internal = Encoding::UTF_8 - end +silence_warnings do + Encoding.default_external = Encoding::UTF_8 + Encoding.default_internal = Encoding::UTF_8 end module Rails diff --git a/railties/lib/rails/commands/plugin.rb b/railties/lib/rails/commands/plugin.rb index c99a2e6685..4ddd12ae0b 100644 --- a/railties/lib/rails/commands/plugin.rb +++ b/railties/lib/rails/commands/plugin.rb @@ -478,7 +478,7 @@ class RecursiveHTTPFetcher def initialize(urls_to_fetch, level = 1, cwd = ".") @level = level @cwd = cwd - @urls_to_fetch = RUBY_VERSION >= '1.9' ? urls_to_fetch.lines : urls_to_fetch.to_a + @urls_to_fetch = urls_to_fetch.lines @quiet = false end diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 197b692469..0ed1eb4af8 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -60,9 +60,6 @@ module Rails class_option :help, :type => :boolean, :aliases => "-h", :group => :rails, :desc => "Show this help message and quit" - - class_option :old_style_hash, :type => :boolean, :default => false, - :desc => "Force using old style hash (:foo => 'bar') on Ruby >= 1.9" end def initialize(*args) @@ -185,11 +182,7 @@ module Rails end def ruby_debugger_gemfile_entry - if RUBY_VERSION < "1.9" - "gem 'ruby-debug'" - else - "gem 'ruby-debug19', :require => 'ruby-debug'" - end + "gem 'ruby-debug19', :require => 'ruby-debug'" end def assets_gemfile_entry @@ -255,14 +248,9 @@ module Rails create_file("#{destination}/.gitkeep") unless options[:skip_git] end - # Returns Ruby 1.9 style key-value pair if current code is running on - # Ruby 1.9.x. Returns the old-style (with hash rocket) otherwise. + # Returns Ruby 1.9 style key-value pair. def key_value(key, value) - if options[:old_style_hash] || RUBY_VERSION < '1.9' - ":#{key} => #{value}" - else - "#{key}: #{value}" - end + "#{key}: #{value}" end end end diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index c6c0392f43..e96fc63ee9 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -9,9 +9,6 @@ module Rails class_option :skip_namespace, :type => :boolean, :default => false, :desc => "Skip namespace (affects only isolated applications)" - class_option :old_style_hash, :type => :boolean, :default => false, - :desc => "Force using old style hash (:foo => 'bar') on Ruby >= 1.9" - def initialize(args, *options) #:nodoc: @inside_template = nil # Unfreeze name in case it's given as a frozen string @@ -185,14 +182,9 @@ module Rails end end - # Returns Ruby 1.9 style key-value pair if current code is running on - # Ruby 1.9.x. Returns the old-style (with hash rocket) otherwise. + # Returns Ruby 1.9 style key-value pair. def key_value(key, value) - if options[:old_style_hash] || RUBY_VERSION < '1.9' - ":#{key} => #{value}" - else - "#{key}: #{value}" - end + "#{key}: #{value}" end end end diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 082642d5cd..5e9c385ab8 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -5,7 +5,6 @@ source 'https://rubygems.org' <%= database_gemfile_entry -%> <%= "gem 'jruby-openssl'\n" if defined?(JRUBY_VERSION) -%> -<%= "gem 'json'\n" if RUBY_VERSION < "1.9.2" -%> <%= assets_gemfile_entry %> <%= javascript_gemfile_entry %> @@ -20,7 +19,7 @@ source 'https://rubygems.org' # gem 'unicorn' # Deploy with Capistrano -# gem 'capistrano' +# gem 'capistrano', :group => :development # To use debugger # <%= ruby_debugger_gemfile_entry %> diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake index 1e7da5ccae..1c28b2c8e6 100644 --- a/railties/lib/rails/tasks/documentation.rake +++ b/railties/lib/rails/tasks/documentation.rake @@ -63,7 +63,7 @@ namespace :doc do rdoc.template = "#{ENV['template']}.rb" if ENV['template'] rdoc.title = "Rails Framework Documentation" rdoc.options << '--line-numbers' - rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('README.rdoc') gem_path('actionmailer') do |actionmailer| %w(README.rdoc CHANGELOG.md MIT-LICENSE lib/action_mailer/base.rb).each do |file| diff --git a/railties/railties.gemspec b/railties/railties.gemspec index a7b9407daf..82655ad394 100644 --- a/railties/railties.gemspec +++ b/railties/railties.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.version = version s.summary = 'Tools for creating, working with, and running Rails applications.' s.description = 'Rails internals: application bootup, plugins, generators, and rake tasks.' - s.required_ruby_version = '>= 1.8.7' + s.required_ruby_version = '>= 1.9.3' s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 28ffff58ca..8f2e6e9ac0 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -189,12 +189,8 @@ module ApplicationTests end def assert_utf8 - if RUBY_VERSION < '1.9' - assert_equal "UTF8", $KCODE - else - assert_equal Encoding::UTF_8, Encoding.default_external - assert_equal Encoding::UTF_8, Encoding.default_internal - end + assert_equal Encoding::UTF_8, Encoding.default_external + assert_equal Encoding::UTF_8, Encoding.default_internal end test "skipping config.encoding still results in 'utf-8' as the default" do diff --git a/railties/test/application/initializers/check_ruby_version_test.rb b/railties/test/application/initializers/check_ruby_version_test.rb deleted file mode 100644 index df7e9696a9..0000000000 --- a/railties/test/application/initializers/check_ruby_version_test.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "isolation/abstract_unit" - -module ApplicationTests - class CheckRubyVersionTest < Test::Unit::TestCase - include ActiveSupport::Testing::Isolation - - def setup - build_app - boot_rails - end - - def teardown - teardown_app - end - - test "rails initializes with ruby 1.8.7 or later, except for 1.9.1" do - if RUBY_VERSION < '1.8.7' - assert_rails_does_not_boot - elsif RUBY_VERSION == '1.9.1' - assert_rails_does_not_boot - else - assert_rails_boots - end - end - - def assert_rails_boots - assert_nothing_raised "It appears that rails does not boot" do - require "rails/all" - end - end - - def assert_rails_does_not_boot - $stderr = File.open("/dev/null", "w") - assert_raises(SystemExit) do - require "rails/all" - end - end - end -end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index c456347e5c..a15943dfc6 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -285,17 +285,10 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_inclusion_of_ruby_debug + def test_inclusion_of_ruby_debug19 run_generator assert_file "Gemfile" do |contents| - assert_match(/gem 'ruby-debug'/, contents) if RUBY_VERSION < '1.9' - end - end - - def test_inclusion_of_ruby_debug19_if_ruby19 - run_generator - assert_file "Gemfile" do |contents| - assert_match(/gem 'ruby-debug19', :require => 'ruby-debug'/, contents) unless RUBY_VERSION < '1.9' + assert_match(/gem 'ruby-debug19', :require => 'ruby-debug'/, contents) end end @@ -337,18 +330,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_new_hash_style run_generator [destination_root] assert_file "config/initializers/session_store.rb" do |file| - if RUBY_VERSION < "1.9" - assert_match(/config.session_store :cookie_store, :key => '_.+_session'/, file) - else - assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) - end - end - end - - def test_force_old_style_hash - run_generator [destination_root, "--old-style-hash"] - assert_file "config/initializers/session_store.rb" do |file| - assert_match(/config.session_store :cookie_store, :key => '_.+_session'/, file) + assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) end end diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb index 139d6b1421..c501780e7f 100644 --- a/railties/test/generators/mailer_generator_test.rb +++ b/railties/test/generators/mailer_generator_test.rb @@ -10,11 +10,7 @@ class MailerGeneratorTest < Rails::Generators::TestCase run_generator assert_file "app/mailers/notifier.rb" do |mailer| assert_match(/class Notifier < ActionMailer::Base/, mailer) - if RUBY_VERSION < "1.9" - assert_match(/default :from => "from@example.com"/, mailer) - else - assert_match(/default from: "from@example.com"/, mailer) - end + assert_match(/default from: "from@example.com"/, mailer) end end @@ -77,33 +73,14 @@ class MailerGeneratorTest < Rails::Generators::TestCase assert_file "app/mailers/notifier.rb" do |mailer| assert_instance_method :foo, mailer do |foo| - if RUBY_VERSION < "1.9" - assert_match(/mail :to => "to@example.org"/, foo) - else - assert_match(/mail to: "to@example.org"/, foo) - end + assert_match(/mail to: "to@example.org"/, foo) assert_match(/@greeting = "Hi"/, foo) end assert_instance_method :bar, mailer do |bar| - if RUBY_VERSION < "1.9" - assert_match(/mail :to => "to@example.org"/, bar) - else - assert_match(/mail to: "to@example.org"/, bar) - end + assert_match(/mail to: "to@example.org"/, bar) assert_match(/@greeting = "Hi"/, bar) end end end - - def test_force_old_style_hash - run_generator ["notifier", "foo", "--old-style-hash"] - assert_file "app/mailers/notifier.rb" do |mailer| - assert_match(/default :from => "from@example.com"/, mailer) - - assert_instance_method :foo, mailer do |foo| - assert_match(/mail :to => "to@example.org"/, foo) - end - end - end end diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index dd1e4bdac1..5c63b13dce 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -155,11 +155,7 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase assert_file "app/mailers/test_app/notifier.rb" do |mailer| assert_match(/module TestApp/, mailer) assert_match(/class Notifier < ActionMailer::Base/, mailer) - if RUBY_VERSION < "1.9" - assert_match(/default :from => "from@example.com"/, mailer) - else - assert_match(/default from: "from@example.com"/, mailer) - end + assert_match(/default from: "from@example.com"/, mailer) end end diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 65b30b9fbd..1382133d7b 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -126,18 +126,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_new_hash_style run_generator assert_file "app/controllers/users_controller.rb" do |content| - if RUBY_VERSION < "1.9" - assert_match(/\{ render :action => "new" \}/, content) - else - assert_match(/\{ render action: "new" \}/, content) - end - end - end - - def test_force_old_style_hash - run_generator ["User", "--old-style-hash"] - assert_file "app/controllers/users_controller.rb" do |content| - assert_match(/\{ render :action => "new" \}/, content) + assert_match(/\{ render action: "new" \}/, content) end end end diff --git a/railties/test/railties/generators_test.rb b/railties/test/railties/generators_test.rb index f8540d69d9..6ebbabc0ff 100644 --- a/railties/test/railties/generators_test.rb +++ b/railties/test/railties/generators_test.rb @@ -46,10 +46,6 @@ module RailtiesTests gem 'rails', :path => '#{RAILS_FRAMEWORK_ROOT}' gem 'sqlite3' - - if RUBY_VERSION < '1.9' - gem "ruby-debug", ">= 0.10.3" - end GEMFILE end end |