Решение на Четвърта задача - Unit тестване от Божидар Михайлов

Обратно към всички решения

Към профила на Божидар Михайлов

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 15 успешни тест(а)
  • 4 неуспешни тест(а)

Код

describe Version do
describe '#initialize' do
context 'initialization with correct args' do
it 'initializes with no arg' do
expect { Version.new }.to_not raise_error(Exception)
end
it 'initializes with empty arg' do
expect { Version.new('') }.to_not raise_error(Exception)
end
it 'initializes from a correct version string' do
expect { Version.new('1.3.17') }.to_not raise_error(Exception)
end
it 'initializes from another Version object' do
version_str = '1.3.17'
from_str = Version.new(version_str)
expect(Version.new(from_str)).to eq(Version.new(version_str))
end
end
context 'initialization with incorrect args' do
it 'doesn\'t initialize from a string containing space' do
version = '1.3. .17'
expected_msg = "Invalid version string '#{version}'"
expect do
Version.new(version)
end.to raise_error(ArgumentError, expected_msg)
end
it 'doesn\'t initialize from an untrimmed string' do
version = ' 1.3.17 '
expected_msg = "Invalid version string '#{version}'"
expect do
Version.new(version)
end.to raise_error(ArgumentError, expected_msg)
end
it 'doesn\'t initialize from a string containing letters' do
version = '1.5.a'
expected_msg = "Invalid version string '#{version}'"
expect do
Version.new(version)
end.to raise_error(ArgumentError, expected_msg)
end
it 'doesn\'t initialize from a string starting with a dot' do
version = '.1.3.17'
expected_msg = "Invalid version string '#{version}'"
expect do
Version.new(version)
end.to raise_error(ArgumentError, expected_msg)
end
it 'doesn\'t initialize from a string ending with a dot' do
version = '1.3.17.'
expected_msg = "Invalid version string '#{version}'"
expect do
Version.new(version)
end.to raise_error(ArgumentError, expected_msg)
end
it 'doesn\'t initialize from a string with consecutive dots' do
version = '1.3..17'
expected_msg = "Invalid version string '#{version}'"
expect do
Version.new(version)
end.to raise_error(ArgumentError, expected_msg)
end
end
end
describe '#to_s' do
it 'returns same if initialized with a canonical version' do
version = '1.3.17'
expect(Version.new(version).to_s).to eq(version)
end
it 'strips zeros if initialized with a non-canonical version' do
version = '1.7.19.0.0'
expected_version = '1.7.19'
expect(Version.new(version).to_s).to eq(expected_version)
end
end
describe '#<' do
it 'returns true for a (lesser, greater) pair' do
lesser = Version.new('1.3.17')
greater = Version.new('1.5.17')
expect(lesser < greater).to be true
end
it 'returns false for a (greater, lesser) pair' do
lesser = Version.new('1.3.17')
greater = Version.new('1.5.17')
expect(greater < lesser).to be false
end
it 'returns false for an equal pair' do
version_str = '1.3.17'
first = Version.new(version_str)
second = Version.new(version_str)
expect(first < second).to be false
end
end
describe '#<=' do
it 'returns true for a (lesser, greater) pair' do
lesser = Version.new('1.4.3')
greater = Version.new('1.4.5.0')
expect(lesser <= greater).to be true
end
it 'returns false for a (greater, lesser) pair' do
lesser = Version.new('1.9.17')
greater = Version.new('1.13.17')
expect(greater <= lesser).to be false
end
it 'returns true for an equal pair' do
version_str = '1.3.17'
first = Version.new(version_str)
second = Version.new(version_str)
expect(first <= second).to be true
end
end
describe '#>' do
it 'returns true for a (greater, lesser) pair' do
lesser = Version.new('1.3.17')
greater = Version.new('1.5.17')
expect(greater > lesser).to be true
end
it 'returns false for a (lesser, greater) pair' do
lesser = Version.new('2.13.4')
greater = Version.new('7.3.15')
expect(lesser > greater).to be false
end
it 'returns false for an equal pair' do
version_str = '18.3.31'
first = Version.new(version_str)
second = Version.new(version_str)
expect(first > second).to be false
end
end
describe '#>=' do
it 'returns true a (greater, lesser) pair' do
lesser = Version.new('1.4.3')
greater = Version.new('1.4.5.0')
expect(greater >= lesser).to be true
end
it 'returns false for a (lesser, greater) pair' do
lesser = Version.new('1.9.17')
greater = Version.new('1.13.17')
expect(lesser >= greater).to be false
end
it 'returns true an equal pair' do
version_str = '1.3.17'
first = Version.new(version_str)
second = Version.new(version_str)
expect(first >= second).to be true
end
end
describe '#==' do
it 'returns true for versions initialized from the same string' do
version_str = '1.2.3'
first = Version.new(version_str)
second = Version.new(version_str)
expect(first == second).to be true
end
it 'returns true for eq versions, one is noncanonical' do
first = Version.new('1.2.3')
second = Version.new('1.2.3.0.0')
expect(first == second).to be true
end
it 'returns false for different versions with equal length' do
first = Version.new('13.4.17')
second = Version.new('17.3.5')
expect(first == second).to be false
end
it 'returns false for different versions of differing length' do
first = Version.new('17.3.0')
second = Version.new('13.4.17.0.0')
expect(first == second).to be false
end
end
describe '#<=>' do
it 'returns -1 for a (lesser, greater) pair with eq lengths' do
lesser = Version.new('1.4.3')
greater = Version.new('1.4.5')
expect(lesser <=> greater).to eq(-1)
end
it 'returns -1 for a (lesser, greater) pair with diff lengths' do
lesser = Version.new('1.4.3')
greater = Version.new('1.4.5.0')
expect(lesser <=> greater).to eq(-1)
end
it 'returns 1 for a (greater, lesser) pair with eq lengths' do
lesser = Version.new('1.9.17')
greater = Version.new('1.13.17')
expect(greater <=> lesser).to eq(1)
end
it 'returns 0 for an equal pair with eq lengths' do
version_str = '1.3.17'
first = Version.new(version_str)
second = Version.new(version_str)
expect(first <=> second).to eq(0)
end
it 'returns 0 for an equal pair with diff lengths' do
first = Version.new('1.3.17.0')
second = Version.new('1.3.17.0.0')
expect(first <=> second).to eq(0)
end
end
describe '#components' do
context 'component count is not provided' do
it 'is correct for a canonical version' do
version_str = '1.2.3.17'
expected_components = [1, 2, 3, 17]
expect(Version.new(version_str).components).to eq(expected_components)
end
it 'is correct for a noncanonical version' do
version_str = '1.2.3.0.0'
expected_components = [1, 2, 3]
expect(Version.new(version_str).components).to eq(expected_components)
end
end
context 'component count is provided' do
it 'is correct when component count is eq to canonical length' do
version_str = '13.15.3'
expected_comps = [13, 15, 3]
expect(Version.new(version_str).components(3)).to eq(expected_comps)
end
it 'is correct when component count is less than canonical length' do
version_str = '13.15.3.5'
expected = [13, 15, 3]
expect(Version.new(version_str).components(3)).to eq(expected)
end
it 'is correct when component count is more than canonical length' do
version_str = '13.15'
expected = [13, 15, 0, 0]
expect(Version.new(version_str).components(4)).to eq(expected)
end
end
it 'does not allow state modification through returned array' do
initial_version = Version.new('3.5.7')
expected_components = [3, 5, 7]
initial_version.components[2] = 'CHANGED'
expect(initial_version.components).to eq(expected_components )
end
end
end
describe Version::Range do
describe '#initialize' do
context 'initialization with correct args' do
it 'initializes with two Versions' do
create_range = proc { Range.new(Version.new, Version.new) }
expect { create_range.call }.to_not raise_error(Exception)
end
it 'initializes with an empty String and a Version' do
create_range = proc { Range.new('', Version.new) }
expect { create_range.call }.to_not raise_error(Exception)
end
it 'initializes with a String and a Version' do
create_range = proc { Range.new('1.5.3.7', Version.new) }
expect { create_range.call }.to_not raise_error(Exception)
end
it 'initializes with a Version and an empty String' do
create_range = proc { Range.new(Version.new, '') }
expect { create_range.call }.to_not raise_error(Exception)
end
it 'initializes with a Version and a String' do
create_range = proc { Range.new(Version.new, '1.5.3.7') }
expect { create_range.call }.to_not raise_error(Exception)
end
end
context 'initialization with incorrect args' do
it 'doesn\'t initialize with an invalid String for first arg' do
version = '1.3.b'
expected_msg = "Invalid version string '#{version}'"
expect do
Version::Range.new(version, '')
end.to raise_error(ArgumentError, expected_msg)
end
it 'doesn\'t initialize with an invalid String for second arg' do
version = '1.b.0'
expected_msg = "Invalid version string '#{version}'"
expect do
Version::Range.new('', version)
end.to raise_error(ArgumentError, expected_msg)
end
end
end
describe '#include?' do
it 'returns true when arg is within Range' do
range = Version::Range.new('1.5', '1.9.3')
version = Version.new('1.7.3')
expect(range.include?(version)).to be true
end
it 'returns false when arg is outside of Range' do
range = Version::Range.new('1.5', '1.9.3')
version = Version.new('1.17.3')
expect(range.include?(version)).to be false
end
end
describe '#to_a' do
it 'handles close start and end' do
range = Range.new('1.5.5', '1.5.8')
expected_arr = ['1.5.5', '1.5.6', '1.5.7', '1.5.8']
expect(range.to_a).to eq(expected_arr)
end
it 'handles patch version overflow' do
range = Range.new('1.5.9', '1.6.1')
expected_arr = ['1.5.9', '1.6.0', '1.6.1']
expect(range.to_a).to eq(expected_arr)
end
it 'handles minor version overflow' do
range = Range.new('1.9.9', '2.0.1')
expected_arr = ['1.9.9', '2.0.0', '2.0.1']
expect(range.to_a).to eq(expected_arr)
end
end
end

Лог от изпълнението

.............F..FFF

Failures:

  1) spec Version::Range tests constructing ranges with versions
     Failure/Error: expect(@solution).to_not pass_tests
       expected this solution to not pass the tests:
       
         class Version
           VALID_VERSION_REGEXP = /\A\z|\A[0-9]+(\.[0-9]+)*\z/
         
           include Comparable
         
           def initialize(version = '')
             unless VALID_VERSION_REGEXP.match(version.to_s)
               raise ArgumentError, "Invalid version string '#{version}'"
             end
         
             @components = version.to_s
               .split('.')
               .map(&:to_i)
               .reverse
               .drop_while(&:zero?)
               .reverse
           end
         
           def <=>(other)
             @components <=> Version.new(other).internal_components
           end
         
           def internal_components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def to_s
             @components.join('.')
           end
         
           class Range
             include Enumerable
         
             def initialize(start_version, end_version)
               raise 'error' if start_version.is_a?(Version) || end_version.is_a?(Version)
             
               @start_version = Version.new(start_version)
               @end_version   = Version.new(end_version)
             end
         
             def include?(version)
               (@start_version <=> version) < 1 && (@end_version <=> version) == 1
             end
         
             def each
               current_version = @start_version
         
               while (current_version <=> @end_version) == -1
                 yield current_version
         
                 current_version = increment_version(current_version)
               end
             end
         
             private
         
             def increment_version(version)
               components = version.internal_components(3)
         
               components[2] += 1
         
               components.to_enum.with_index.reverse_each do |_, index|
                 component = components[index]
         
                 if component >= 10 && components[index - 1]
                   components[index]      = 0
                   components[index - 1] += 1
                 end
               end
         
               Version.new(components.join('.'))
             end
           end
         end
     # /tmp/d20161119-19072-b3ufqt/spec.rb:492:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) spec Version::Range tests include? with versions lower than the start one
     Failure/Error: expect(@solution).to_not pass_tests
       expected this solution to not pass the tests:
       
         class Version
           VALID_VERSION_REGEXP = /\A\z|\A[0-9]+(\.[0-9]+)*\z/
         
           include Comparable
         
           def initialize(version = '')
             unless VALID_VERSION_REGEXP.match(version.to_s)
               raise ArgumentError, "Invalid version string '#{version}'"
             end
         
             @components = version.to_s
               .split('.')
               .map(&:to_i)
               .reverse
               .drop_while(&:zero?)
               .reverse
           end
         
           def <=>(other)
             @components <=> Version.new(other).internal_components
           end
         
           def internal_components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def to_s
             @components.join('.')
           end
         
           class Range
             include Enumerable
         
             def initialize(start_version, end_version)
               @start_version = Version.new(start_version)
               @end_version   = Version.new(end_version)
             end
         
             def include?(version)
               @end_version > version
             end
         
             def each
               current_version = @start_version
         
               while (current_version <=> @end_version) == -1
                 yield current_version
         
                 current_version = increment_version(current_version)
               end
             end
         
             private
         
             def increment_version(version)
               components = version.internal_components(3)
         
               components[2] += 1
         
               components.to_enum.with_index.reverse_each do |_, index|
                 component = components[index]
         
                 if component >= 10 && components[index - 1]
                   components[index]      = 0
                   components[index - 1] += 1
                 end
               end
         
               Version.new(components.join('.'))
             end
           end
         end
     # /tmp/d20161119-19072-b3ufqt/spec.rb:522:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) spec Version::Range smoke-tests #to_a
     Failure/Error: expect(@solution).to_not pass_tests
       expected this solution to not pass the tests:
       
         class Version
           VALID_VERSION_REGEXP = /\A\z|\A[0-9]+(\.[0-9]+)*\z/
         
           include Comparable
         
           def initialize(version = '')
             unless VALID_VERSION_REGEXP.match(version.to_s)
               raise ArgumentError, "Invalid version string '#{version}'"
             end
         
             @components = version.to_s
               .split('.')
               .map(&:to_i)
               .reverse
               .drop_while(&:zero?)
               .reverse
           end
         
           def <=>(other)
             @components <=> Version.new(other).internal_components
           end
         
           def internal_components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def to_s
             @components.join('.')
           end
         
           class Range
           def to_a
             []
           end
             include Enumerable
         
             def initialize(start_version, end_version)
               @start_version = Version.new(start_version)
               @end_version   = Version.new(end_version)
             end
         
             def include?(version)
               (@start_version <=> version) < 1 && (@end_version <=> version) == 1
             end
         
             def each
               current_version = @start_version
         
               while (current_version <=> @end_version) == -1
                 yield current_version
         
                 current_version = increment_version(current_version)
               end
             end
         
             private
         
             def increment_version(version)
               components = version.internal_components(3)
         
               components[2] += 1
         
               components.to_enum.with_index.reverse_each do |_, index|
                 component = components[index]
         
                 if component >= 10 && components[index - 1]
                   components[index]      = 0
                   components[index - 1] += 1
                 end
               end
         
               Version.new(components.join('.'))
             end
           end
         end
     # /tmp/d20161119-19072-b3ufqt/spec.rb:532:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  4) spec Version::Range tests each #to_a element
     Failure/Error: expect(@solution).to_not pass_tests
       expected this solution to not pass the tests:
       
         class Version
           VALID_VERSION_REGEXP = /\A\z|\A[0-9]+(\.[0-9]+)*\z/
         
           include Comparable
         
           def initialize(version = '')
             unless VALID_VERSION_REGEXP.match(version.to_s)
               raise ArgumentError, "Invalid version string '#{version}'"
             end
         
             @components = version.to_s
               .split('.')
               .map(&:to_i)
               .reverse
               .drop_while(&:zero?)
               .reverse
           end
         
           def <=>(other)
             @components <=> Version.new(other).internal_components
           end
         
           def internal_components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def components(positions = 0)
             padding_size = positions - @components.size
         
             if padding_size > 0
               @components + [0] * padding_size
             elsif positions != 0
               @components.take(positions)
             else
               @components.dup
             end
           end
         
           def to_s
             @components.join('.')
           end
         
           class Range
           def to_a
             versions = enum_for(:each).to_a
             versions[1..-2] = [42] * (versions.size - 2)
             versions
           end
             include Enumerable
         
             def initialize(start_version, end_version)
               @start_version = Version.new(start_version)
               @end_version   = Version.new(end_version)
             end
         
             def include?(version)
               (@start_version <=> version) < 1 && (@end_version <=> version) == 1
             end
         
             def each
               current_version = @start_version
         
               while (current_version <=> @end_version) == -1
                 yield current_version
         
                 current_version = increment_version(current_version)
               end
             end
         
             private
         
             def increment_version(version)
               components = version.internal_components(3)
         
               components[2] += 1
         
               components.to_enum.with_index.reverse_each do |_, index|
                 component = components[index]
         
                 if component >= 10 && components[index - 1]
                   components[index]      = 0
                   components[index - 1] += 1
                 end
               end
         
               Version.new(components.join('.'))
             end
           end
         end
     # /tmp/d20161119-19072-b3ufqt/spec.rb:544:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 18.89 seconds
19 examples, 4 failures

Failed examples:

rspec /tmp/d20161119-19072-b3ufqt/spec.rb:482 # spec Version::Range tests constructing ranges with versions
rspec /tmp/d20161119-19072-b3ufqt/spec.rb:515 # spec Version::Range tests include? with versions lower than the start one
rspec /tmp/d20161119-19072-b3ufqt/spec.rb:525 # spec Version::Range smoke-tests #to_a
rspec /tmp/d20161119-19072-b3ufqt/spec.rb:535 # spec Version::Range tests each #to_a element

История (1 версия и 0 коментара)

Божидар обнови решението на 18.11.2016 19:17 (преди почти 2 години)

+describe Version do
+ describe '#initialize' do
+ context 'initialization with correct args' do
+ it 'initializes with no arg' do
+ expect { Version.new }.to_not raise_error(Exception)
+ end
+
+ it 'initializes with empty arg' do
+ expect { Version.new('') }.to_not raise_error(Exception)
+ end
+
+ it 'initializes from a correct version string' do
+ expect { Version.new('1.3.17') }.to_not raise_error(Exception)
+ end
+
+ it 'initializes from another Version object' do
+ version_str = '1.3.17'
+ from_str = Version.new(version_str)
+
+ expect(Version.new(from_str)).to eq(Version.new(version_str))
+ end
+ end
+
+ context 'initialization with incorrect args' do
+ it 'doesn\'t initialize from a string containing space' do
+ version = '1.3. .17'
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version.new(version)
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+
+ it 'doesn\'t initialize from an untrimmed string' do
+ version = ' 1.3.17 '
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version.new(version)
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+
+ it 'doesn\'t initialize from a string containing letters' do
+ version = '1.5.a'
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version.new(version)
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+
+ it 'doesn\'t initialize from a string starting with a dot' do
+ version = '.1.3.17'
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version.new(version)
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+
+ it 'doesn\'t initialize from a string ending with a dot' do
+ version = '1.3.17.'
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version.new(version)
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+
+ it 'doesn\'t initialize from a string with consecutive dots' do
+ version = '1.3..17'
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version.new(version)
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+ end
+ end
+
+ describe '#to_s' do
+ it 'returns same if initialized with a canonical version' do
+ version = '1.3.17'
+
+ expect(Version.new(version).to_s).to eq(version)
+ end
+
+ it 'strips zeros if initialized with a non-canonical version' do
+ version = '1.7.19.0.0'
+ expected_version = '1.7.19'
+
+ expect(Version.new(version).to_s).to eq(expected_version)
+ end
+ end
+
+ describe '#<' do
+ it 'returns true for a (lesser, greater) pair' do
+ lesser = Version.new('1.3.17')
+ greater = Version.new('1.5.17')
+
+ expect(lesser < greater).to be true
+ end
+
+ it 'returns false for a (greater, lesser) pair' do
+ lesser = Version.new('1.3.17')
+ greater = Version.new('1.5.17')
+
+ expect(greater < lesser).to be false
+ end
+
+ it 'returns false for an equal pair' do
+ version_str = '1.3.17'
+ first = Version.new(version_str)
+ second = Version.new(version_str)
+
+ expect(first < second).to be false
+ end
+ end
+
+ describe '#<=' do
+ it 'returns true for a (lesser, greater) pair' do
+ lesser = Version.new('1.4.3')
+ greater = Version.new('1.4.5.0')
+
+ expect(lesser <= greater).to be true
+ end
+
+ it 'returns false for a (greater, lesser) pair' do
+ lesser = Version.new('1.9.17')
+ greater = Version.new('1.13.17')
+
+ expect(greater <= lesser).to be false
+ end
+
+ it 'returns true for an equal pair' do
+ version_str = '1.3.17'
+ first = Version.new(version_str)
+ second = Version.new(version_str)
+
+ expect(first <= second).to be true
+ end
+ end
+
+ describe '#>' do
+ it 'returns true for a (greater, lesser) pair' do
+ lesser = Version.new('1.3.17')
+ greater = Version.new('1.5.17')
+
+ expect(greater > lesser).to be true
+ end
+
+ it 'returns false for a (lesser, greater) pair' do
+ lesser = Version.new('2.13.4')
+ greater = Version.new('7.3.15')
+
+ expect(lesser > greater).to be false
+ end
+
+ it 'returns false for an equal pair' do
+ version_str = '18.3.31'
+ first = Version.new(version_str)
+ second = Version.new(version_str)
+
+ expect(first > second).to be false
+ end
+ end
+
+ describe '#>=' do
+ it 'returns true a (greater, lesser) pair' do
+ lesser = Version.new('1.4.3')
+ greater = Version.new('1.4.5.0')
+
+ expect(greater >= lesser).to be true
+ end
+
+ it 'returns false for a (lesser, greater) pair' do
+ lesser = Version.new('1.9.17')
+ greater = Version.new('1.13.17')
+
+ expect(lesser >= greater).to be false
+ end
+
+ it 'returns true an equal pair' do
+ version_str = '1.3.17'
+ first = Version.new(version_str)
+ second = Version.new(version_str)
+
+ expect(first >= second).to be true
+ end
+ end
+
+ describe '#==' do
+ it 'returns true for versions initialized from the same string' do
+ version_str = '1.2.3'
+ first = Version.new(version_str)
+ second = Version.new(version_str)
+
+ expect(first == second).to be true
+ end
+
+ it 'returns true for eq versions, one is noncanonical' do
+ first = Version.new('1.2.3')
+ second = Version.new('1.2.3.0.0')
+
+ expect(first == second).to be true
+ end
+
+ it 'returns false for different versions with equal length' do
+ first = Version.new('13.4.17')
+ second = Version.new('17.3.5')
+
+ expect(first == second).to be false
+ end
+
+ it 'returns false for different versions of differing length' do
+ first = Version.new('17.3.0')
+ second = Version.new('13.4.17.0.0')
+
+ expect(first == second).to be false
+ end
+ end
+
+ describe '#<=>' do
+ it 'returns -1 for a (lesser, greater) pair with eq lengths' do
+ lesser = Version.new('1.4.3')
+ greater = Version.new('1.4.5')
+
+ expect(lesser <=> greater).to eq(-1)
+ end
+
+ it 'returns -1 for a (lesser, greater) pair with diff lengths' do
+ lesser = Version.new('1.4.3')
+ greater = Version.new('1.4.5.0')
+
+ expect(lesser <=> greater).to eq(-1)
+ end
+
+ it 'returns 1 for a (greater, lesser) pair with eq lengths' do
+ lesser = Version.new('1.9.17')
+ greater = Version.new('1.13.17')
+
+ expect(greater <=> lesser).to eq(1)
+ end
+
+ it 'returns 0 for an equal pair with eq lengths' do
+ version_str = '1.3.17'
+ first = Version.new(version_str)
+ second = Version.new(version_str)
+
+ expect(first <=> second).to eq(0)
+ end
+
+ it 'returns 0 for an equal pair with diff lengths' do
+ first = Version.new('1.3.17.0')
+ second = Version.new('1.3.17.0.0')
+
+ expect(first <=> second).to eq(0)
+ end
+ end
+
+ describe '#components' do
+ context 'component count is not provided' do
+ it 'is correct for a canonical version' do
+ version_str = '1.2.3.17'
+ expected_components = [1, 2, 3, 17]
+
+ expect(Version.new(version_str).components).to eq(expected_components)
+ end
+
+ it 'is correct for a noncanonical version' do
+ version_str = '1.2.3.0.0'
+ expected_components = [1, 2, 3]
+
+ expect(Version.new(version_str).components).to eq(expected_components)
+ end
+ end
+
+ context 'component count is provided' do
+ it 'is correct when component count is eq to canonical length' do
+ version_str = '13.15.3'
+ expected_comps = [13, 15, 3]
+
+ expect(Version.new(version_str).components(3)).to eq(expected_comps)
+ end
+
+ it 'is correct when component count is less than canonical length' do
+ version_str = '13.15.3.5'
+ expected = [13, 15, 3]
+
+ expect(Version.new(version_str).components(3)).to eq(expected)
+ end
+
+ it 'is correct when component count is more than canonical length' do
+ version_str = '13.15'
+ expected = [13, 15, 0, 0]
+
+ expect(Version.new(version_str).components(4)).to eq(expected)
+ end
+ end
+
+ it 'does not allow state modification through returned array' do
+ initial_version = Version.new('3.5.7')
+ expected_components = [3, 5, 7]
+ initial_version.components[2] = 'CHANGED'
+
+ expect(initial_version.components).to eq(expected_components )
+ end
+ end
+end
+
+describe Version::Range do
+ describe '#initialize' do
+ context 'initialization with correct args' do
+ it 'initializes with two Versions' do
+ create_range = proc { Range.new(Version.new, Version.new) }
+ expect { create_range.call }.to_not raise_error(Exception)
+ end
+
+ it 'initializes with an empty String and a Version' do
+ create_range = proc { Range.new('', Version.new) }
+ expect { create_range.call }.to_not raise_error(Exception)
+ end
+
+ it 'initializes with a String and a Version' do
+ create_range = proc { Range.new('1.5.3.7', Version.new) }
+ expect { create_range.call }.to_not raise_error(Exception)
+ end
+
+ it 'initializes with a Version and an empty String' do
+ create_range = proc { Range.new(Version.new, '') }
+ expect { create_range.call }.to_not raise_error(Exception)
+ end
+
+ it 'initializes with a Version and a String' do
+ create_range = proc { Range.new(Version.new, '1.5.3.7') }
+ expect { create_range.call }.to_not raise_error(Exception)
+ end
+ end
+
+ context 'initialization with incorrect args' do
+ it 'doesn\'t initialize with an invalid String for first arg' do
+ version = '1.3.b'
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version::Range.new(version, '')
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+
+ it 'doesn\'t initialize with an invalid String for second arg' do
+ version = '1.b.0'
+ expected_msg = "Invalid version string '#{version}'"
+
+ expect do
+ Version::Range.new('', version)
+ end.to raise_error(ArgumentError, expected_msg)
+ end
+ end
+ end
+
+ describe '#include?' do
+ it 'returns true when arg is within Range' do
+ range = Version::Range.new('1.5', '1.9.3')
+ version = Version.new('1.7.3')
+
+ expect(range.include?(version)).to be true
+ end
+
+ it 'returns false when arg is outside of Range' do
+ range = Version::Range.new('1.5', '1.9.3')
+ version = Version.new('1.17.3')
+
+ expect(range.include?(version)).to be false
+ end
+ end
+
+ describe '#to_a' do
+ it 'handles close start and end' do
+ range = Range.new('1.5.5', '1.5.8')
+ expected_arr = ['1.5.5', '1.5.6', '1.5.7', '1.5.8']
+
+ expect(range.to_a).to eq(expected_arr)
+ end
+
+ it 'handles patch version overflow' do
+ range = Range.new('1.5.9', '1.6.1')
+ expected_arr = ['1.5.9', '1.6.0', '1.6.1']
+
+ expect(range.to_a).to eq(expected_arr)
+ end
+
+ it 'handles minor version overflow' do
+ range = Range.new('1.9.9', '2.0.1')
+ expected_arr = ['1.9.9', '2.0.0', '2.0.1']
+
+ expect(range.to_a).to eq(expected_arr)
+ end
+ end
+end