[Haml] Fix version number checks between release/prerelease versions.

Turns out string comparison, despite being the recommended method,
doesn't actually work in all edge cases.

Closes gh-248
This commit is contained in:
Nathan Weizenbaum 2010-08-29 22:33:57 -07:00
parent 2108821480
commit 61a1de3ff7
3 changed files with 64 additions and 1 deletions

View File

@ -12,6 +12,8 @@
* Disambiguate references to the `Rails` module when `haml-rails` is installed.
* Compatibility with Rails 3 final.
## 3.0.17
[Tagged on GitHub](http://github.com/nex3/haml/commit/3.0.17).

View File

@ -231,6 +231,44 @@ module Haml
info
end
# Returns whether one version string represents a more recent version than another.
#
# @param v1 [String] A version string.
# @param v2 [String] Another version string.
# @return [Boolean]
def version_gt(v1, v2)
# Construct an array to make sure the shorter version is padded with nil
Array.new([v1.length, v2.length].max).zip(v1.split("."), v2.split(".")) do |_, p1, p2|
p1 ||= "0"
p2 ||= "0"
release1 = p1 =~ /^[0-9]+$/
release2 = p2 =~ /^[0-9]+$/
if release1 && release2
# Integer comparison if both are full releases
p1, p2 = p1.to_i, p2.to_i
next if p1 == p2
return p1 > p2
elsif !release1 && !release2
# String comparison if both are prereleases
next if p1 == p2
return p1 > p2
else
# If only one is a release, that one is newer
return release1
end
end
end
# Returns whether one version string represents the same or a more
# recent version than another.
#
# @param v1 [String] A version string.
# @param v2 [String] Another version string.
# @return [Boolean]
def version_geq(v1, v2)
version_gt(v1, v2) || !version_gt(v2, v1)
end
# Silence all output to STDERR within a block.
#
# @yield A block in which no output will be printed to STDERR
@ -308,7 +346,7 @@ module Haml
return false unless defined?(ActionPack) && defined?(ActionPack::VERSION) &&
defined?(ActionPack::VERSION::STRING)
ActionPack::VERSION::STRING >= version
version_geq(ActionPack::VERSION::STRING, version)
end
# Returns an ActionView::Template* class.

View File

@ -217,6 +217,29 @@ class UtilTest < Test::Unit::TestCase
assert_equal(["/tmp/foo.rb", 12, "fizzle"], caller_info("/tmp/foo.rb:12: in `fizzle {}'"))
end
def test_version_gt
assert_version_gt("2.0.0", "1.0.0")
assert_version_gt("1.1.0", "1.0.0")
assert_version_gt("1.0.1", "1.0.0")
assert_version_gt("1.0.0", "1.0.0.rc")
assert_version_gt("1.0.0.1", "1.0.0.rc")
assert_version_gt("1.0.0.rc", "0.9.9")
assert_version_gt("1.0.0.beta", "1.0.0.alpha")
assert_version_eq("1.0.0", "1.0.0")
assert_version_eq("1.0.0", "1.0.0.0")
end
def assert_version_gt(v1, v2)
#assert(version_gt(v1, v2), "Expected #{v1} > #{v2}")
assert(!version_gt(v2, v1), "Expected #{v2} < #{v1}")
end
def assert_version_eq(v1, v2)
assert(!version_gt(v1, v2), "Expected #{v1} = #{v2}")
assert(!version_gt(v2, v1), "Expected #{v2} = #{v1}")
end
def test_def_static_method
klass = Class.new
def_static_method(klass, :static_method, [:arg1, :arg2],