[Version] Add a util class that can be used to compare versions.

This commit is contained in:
Eloy Durán
2014-02-26 13:27:29 +01:00
parent 19c2b4af7a
commit 210a577317
3 changed files with 100 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
module Motion; module Util
class Version
include Comparable
def initialize(version)
@version = version.to_s
unless @version =~ /^[.0-9]+$/
raise ArgumentError, "A version may only contain periods and digits."
end
end
def to_s
@version
end
def segments
@segments ||= @version.split('.').map(&:to_i)
end
# This is pretty much vendored straight from RubyGems, except we dont
# care about string segments for our purposes.
#
# https://github.com/rubygems/rubygems/blob/81d806d818baeb5dcb6398ca631d772a003d078e/lib/rubygems/version.rb
#
def <=>(other)
return unless Version === other
return 0 if @version == other.to_s
lhsegments = segments
rhsegments = other.segments
lhsize = lhsegments.size
rhsize = rhsegments.size
limit = (lhsize > rhsize ? lhsize : rhsize) - 1
i = 0
while i <= limit
lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
i += 1
next if lhs == rhs
return lhs <=> rhs
end
return 0
end
end
end; end

6
test/external/Rakefile vendored Normal file
View File

@@ -0,0 +1,6 @@
desc "Run all tests"
task :spec do
sh "bacon **/*_spec.rb"
end
task :default => :spec

47
test/external/unit/version_spec.rb vendored Normal file
View File

@@ -0,0 +1,47 @@
require 'bacon'
$:.unshift File.expand_path('../../../../lib', __FILE__)
require 'motion/util/version'
module Motion; module Util
describe Version do
it "raises if given a string that contains other chars than dots and digits" do
lambda { Version.new(' 1') }.should.raise ArgumentError
lambda { Version.new('1,0') }.should.raise ArgumentError
lambda { Version.new('1.0b1') }.should.raise ArgumentError
end
before do
@version = Version.new('10.6.1')
end
it "returns its segments" do
@version.segments.should == [10, 6, 1]
end
it "is comparable to other versions" do
@version.should == Version.new('10.6.1')
@version.should == Version.new('10.6.1.0')
@version.should <= Version.new('10.6.1.0.0')
@version.should >= Version.new('10.6.1.0.0.0')
@version.should > Version.new('10.6.0')
@version.should > Version.new('9.5.99.0')
@version.should < Version.new('10.6.1.1')
@version.should < Version.new('11.0.0.1')
end
it "returns a string representation" do
@version.to_s.should == '10.6.1'
end
it "creates a new instance from an existing instance" do
other = Version.new(@version)
other.should == @version
other.should.not.eql @version
end
end
end; end