Version comparison using strings can be faulty. #2024

Closed
wants to merge 1 commit into
from
Jump to file
+183 −44
Split
@@ -11,6 +11,8 @@
$VERBOSE = old
end
+require 'active_support/core_ext/rubygems'
+
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/string/encoding'
@@ -12,6 +12,8 @@
ENV['TMPDIR'] = File.join(File.dirname(__FILE__), 'tmp')
+require 'active_support/core_ext/rubygems'
+
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/string/encoding'
@@ -5,9 +5,11 @@
require 'config'
require 'active_model'
+require 'active_support/core_ext/rubygems'
require 'active_support/core_ext/string/access'
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
require 'test/unit'
+
@@ -22,6 +22,7 @@
require 'models/edge'
require 'models/joke'
require 'rexml/document'
+require 'active_support/core_ext/rubygems'
require 'active_support/core_ext/exception'
class Category < ActiveRecord::Base; end
@@ -6,6 +6,7 @@
require 'test/unit'
require 'active_resource'
require 'active_support'
+require 'active_support/core_ext/rubygems'
require 'active_support/test_case'
require 'setter_trap'
@@ -7,7 +7,7 @@
class Date
DAYS_INTO_WEEK = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6 }
- if RUBY_VERSION < '1.9'
+ if Gem.ruby_version < '1.9'
undef :>>
# Backported from 1.9. The one in 1.8 leads to incorrect next_month and
@@ -251,3 +251,4 @@ def tomorrow
self + 1
end
end
+
@@ -67,7 +67,7 @@ def readable_inspect
# In this case, it simply returns +self+.
def to_date
self
- end if RUBY_VERSION < '1.9'
+ end if Gem.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).
@@ -92,15 +92,16 @@ def to_time(form = :local)
# 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'
+ end if Gem.ruby_version < '1.9'
def iso8601
strftime('%F')
- end if RUBY_VERSION < '1.9'
+ end if Gem.ruby_version < '1.9'
- alias_method :rfc3339, :iso8601 if RUBY_VERSION < '1.9'
+ alias_method :rfc3339, :iso8601 if Gem.ruby_version < '1.9'
def xmlschema
to_time_in_current_zone.xmlschema
end
end
+
@@ -9,7 +9,7 @@
#
# 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'
+if Gem.ruby_version < '1.9'
require 'date'
begin
::Date.today.freeze.jd
@@ -31,3 +31,4 @@ def freeze
end
end
end
+
@@ -1,4 +1,4 @@
-require 'rational' unless RUBY_VERSION >= '1.9.2'
+require 'rational' unless Gem.ruby_version >= '1.9.2'
class DateTime
class << self
@@ -130,3 +130,4 @@ def <=>(other)
super other.to_datetime
end
end
+
@@ -66,7 +66,7 @@ def to_date
# 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 * (Gem.ruby_version < '1.9' ? 86400000000 : 1000000)) : self
end
# To be able to keep Times, Dates and DateTimes interchangeable on conversions.
@@ -101,3 +101,4 @@ def seconds_since_unix_epoch
(self - ::DateTime.civil(1970)) * seconds_per_day
end
end
+
@@ -2,7 +2,7 @@
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'
+ remove_method(:group_by) if [].respond_to?(:group_by) && Gem.ruby_version < '1.9'
# Collect an enumerable into sets, grouped by the result of a block. Useful,
# for example, for grouping records by date.
@@ -115,3 +115,4 @@ def sum(identity = 0)
(actual_last - first + 1) * (actual_last + first) / 2
end
end
+
@@ -1,3 +1,4 @@
module ActiveSupport
- FrozenObjectError = RUBY_VERSION < '1.9' ? TypeError : RuntimeError
+ FrozenObjectError = Gem.ruby_version < '1.9' ? TypeError : RuntimeError
end
+
@@ -16,4 +16,5 @@ def round(precision = nil)
precisionless_round
end
end
-end if RUBY_VERSION < '1.9'
+end if Gem.ruby_version < '1.9'
+
@@ -57,7 +57,7 @@ def parents
parents
end
- if RUBY_VERSION < '1.9'
+ if Gem.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
@@ -86,3 +86,4 @@ def local_constant_names
local_constants.map { |c| c.to_s }
end
end
+
@@ -23,11 +23,12 @@ def instance_values #:nodoc:
# end
#
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
- if RUBY_VERSION >= '1.9'
+ if Gem.ruby_version >= '1.9'
def instance_variable_names
instance_variables.map { |var| var.to_s }
end
else
alias_method :instance_variable_names, :instance_variables
end
end
+
@@ -0,0 +1 @@
+require 'active_support/core_ext/rubygems/version'
@@ -0,0 +1,61 @@
+module Gem
+ class Version
+ # Checks if this version is inferior than the other.
+ #
+ # Gem::Version.new("1.8.7") < "1.9.2" #=> true
+ # Gem::Version.new("1.9") < "1.8.7" #=> false
+ #
+ # <tt>Gem.ruby_version < "1.9.2"</tt> can be handy, as <tt>Gem.ruby_version</tt> returns
+ # an object of <tt>Gem::Version</tt>
+ def < other_version
+ (self <=> Version.new(other_version)) == -1
+ end
+
+ # Checks if this version is superior than the other.
+ #
+ # Gem::Version.new("1.8.7") > "1.9.2" #=> false
+ # Gem::Version.new("1.9") > "1.8.7" #=> true
+ #
+ # <tt>Gem.ruby_version > "1.9.2"</tt> can be handy, as <tt>Gem.ruby_version</tt> returns
+ # an object of <tt>Gem::Version</tt>
+ def > other_version
+ (self <=> Version.new(other_version)) == 1
+ end
+
+ # Checks if both the versions are similar.
+ #
+ # Gem::Version.new("1.9.2") == "1.9.2" #=> true
+ # Gem::Version.new("1.9") == "1.8.7" #=> false
+ #
+ # <tt>Gem.ruby_version == "1.9.2"</tt> can be handy, as <tt>Gem.ruby_version</tt> returns
+ # an object of <tt>Gem::Version</tt>
+ def == other_version
+ (self <=> Version.new(other_version)) == 0
+ end
+
+ # Checks if this version is superior or similar to the other.
+ #
+ # Gem::Version.new("1.8.7") >= "1.9.2" #=> false
+ # Gem::Version.new("1.9") >= "1.8.7" #=> true
+ # Gem::Version.new("1.9") >= "1.9" #=> true
+ #
+ # <tt>Gem.ruby_version >= "1.9.2"</tt> can be handy, as <tt>Gem.ruby_version</tt> returns
+ # an object of <tt>Gem::Version</tt>
+ def >= other_version
+ (self > other_version) || (self == other_version)
+ end
+
+ # Checks if this version is inferior or similar to the other.
+ #
+ # Gem::Version.new("1.8.7") <= "1.9.2" #=> true
+ # Gem::Version.new("1.8.7") <= "1.8.7" #=> true
+ # Gem::Version.new("1.9") <= "1.8.7" #=> false
+ #
+ # <tt>Gem.ruby_version <= "1.9.2"</tt> can be handy, as <tt>Gem.ruby_version</tt> returns
+ # an object of <tt>Gem::Version</tt>
+ def <= other_version
+ (self < other_version) || (self == other_version)
+ end
+ end
+end
+
@@ -1,8 +1,9 @@
# encoding: utf-8
+require 'active_support/core_ext/rubygems'
require 'active_support/multibyte'
class String
- if RUBY_VERSION >= "1.9"
+ if Gem.ruby_version >= "1.9"
# == Multibyte proxy
#
# +mb_chars+ is a multibyte safe proxy for string methods.
@@ -70,3 +71,4 @@ def is_utf8?
end
end
end
+
@@ -1,6 +1,6 @@
# encoding: utf-8
-if RUBY_VERSION >= '1.9'
+if Gem.ruby_version >= '1.9'
require 'uri'
str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
@@ -28,3 +28,4 @@ def parser
end
end
end
+
@@ -38,7 +38,7 @@ class Chars
alias to_s wrapped_string
alias to_str wrapped_string
- if RUBY_VERSION >= "1.9"
+ if Gem.ruby_version >= "1.9"
# Creates a new Chars instance by wrapping _string_.
def initialize(string)
@wrapped_string = string
@@ -94,7 +94,7 @@ def <=>(other)
@wrapped_string <=> other.to_s
end
- if RUBY_VERSION < "1.9"
+ if Gem.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)
@@ -475,3 +475,4 @@ def chars(string) #:nodoc:
end
end
end
+
@@ -4,6 +4,7 @@
end
require 'yaml'
+require 'active_support/core_ext/rubygems'
YAML.add_builtin_type("omap") do |type, val|
ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
@@ -48,7 +49,7 @@ def nested_under_indifferent_access
end
# Hash is ordered in Ruby 1.9!
- if RUBY_VERSION < '1.9'
+ if Gem.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.
@@ -215,3 +216,4 @@ def sync_keys!
end
end
end
+
@@ -7,6 +7,8 @@
$VERBOSE = old
end
+require 'active_support/core_ext/rubygems'
+
lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
@@ -31,7 +33,7 @@
require 'active_support'
# Include shims until we get off 1.8.6
-require 'active_support/ruby/shim' if RUBY_VERSION < '1.8.7'
+require 'active_support/ruby/shim' if Gem.ruby_version < '1.8.7'
def uses_memcached(test_name)
require 'memcache'
@@ -44,7 +46,7 @@ def uses_memcached(test_name)
end
def with_kcode(code)
- if RUBY_VERSION < '1.9'
+ if Gem.ruby_version < '1.9'
begin
old_kcode, $KCODE = $KCODE, code
yield
@@ -59,6 +61,7 @@ def with_kcode(code)
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
-if RUBY_VERSION < '1.9'
+if Gem.ruby_version < '1.9'
$KCODE = 'UTF8'
end
+
@@ -374,7 +374,7 @@ def test_xmlschema_when_zone_is_set
end
end
- if RUBY_VERSION < '1.9'
+ if Gem.ruby_version < '1.9'
def test_rfc3339
assert_equal('1980-02-28', Date.new(1980, 2, 28).rfc3339)
end
@@ -461,3 +461,4 @@ def test_can_freeze_twice
end
end
end
+
Oops, something went wrong.