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

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

Към профила на Момчил Баталов

Резултати

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

Код

RSpec.describe 'Version' do
describe '#Version' do
it 'can raise ArgumentError if invalid argument is given' do
expect { Version.new('1.1.5') }.to_not raise_error
expect { Version.new('1.1.5.a') }.to raise_error(
ArgumentError, "Invalid version string '1.1.5.a'"
)
expect { Version.new('.1.5') }.to raise_error(
ArgumentError, "Invalid version string '.1.5'"
)
expect { Version.new('1..5') }.to raise_error(
ArgumentError, "Invalid version string '1..5'"
)
expect { Version.new('1.1.5.') }.to raise_error(
ArgumentError, "Invalid version string '1.1.5.'"
)
end
end
describe '#<=>' do
it 'can do <=>' do
vers1 = Version.new('1.1.5')
vers2 = Version.new('1.1.6')
vers3 = Version.new('1.1.6')
expect(vers1 <=> vers2).to eq(-1)
expect(vers2 <=> vers3).to eq(0)
expect(vers2 <=> vers1).to eq(1)
end
it 'can do <' do
vers1 = Version.new('1.1.5')
vers2 = Version.new('1.1.6')
vers3 = Version.new('1.1.6')
expect(vers1 < vers2).to eq(true)
expect(vers2 < vers3).to eq(false)
expect(vers2 < vers1).to eq(false)
end
it 'can do >' do
vers1 = Version.new('1.1.5')
vers2 = Version.new('1.1.6')
vers3 = Version.new('1.1.6')
expect(vers1 > vers2).to eq(false)
expect(vers2 > vers3).to eq(false)
expect(vers2 > vers1).to eq(true)
end
it 'can do <=' do
vers1 = Version.new('1.1.5')
vers2 = Version.new('1.1.6')
vers3 = Version.new('1.1.6')
expect(vers1 <= vers2).to eq(true)
expect(vers2 <= vers3).to eq(true)
expect(vers2 <= vers1).to eq(false)
end
it 'can do >=' do
vers1 = Version.new('1.1.5')
vers2 = Version.new('1.1.6')
vers3 = Version.new('1.1.6')
expect(vers1 >= vers2).to eq(false)
expect(vers2 >= vers3).to eq(true)
expect(vers2 >= vers1).to eq(true)
end
it 'can do ==' do
vers1 = Version.new('1.1.5.0')
vers2 = Version.new('1.1.5')
vers3 = Version.new('1.5.5')
vers4 = Version.new('1.1.5')
expect(vers1 == vers2).to eq(true)
expect(vers2 == vers4).to eq(true)
expect(vers1 == vers3).to eq(false)
end
end
describe '#to_s' do
it 'can show the version as a string' do
expect(Version.new('1.2.3').to_s).to eq('1.2.3')
end
it 'can show the version as a string without zeroes at the end' do
expect(Version.new('1.2.3.0.0.0').to_s).to eq('1.2.3')
end
it 'can show the version as a string without parameter' do
expect(Version.new.to_s).to eq('')
end
it 'can show the version as a string with empty string parameter' do
expect(Version.new('').to_s).to eq('')
expect(Version.new('0').to_s).to eq('')
end
end
describe '#components' do
it 'can return array of the components' do
expect(Version.new('1.2.3').components).to eq([1, 2, 3])
end
it 'can return array of the components without meaningless zeroes' do
expect(Version.new('1.2.3.0.0').components).to eq([1, 2, 3])
end
it 'can return array with exact number of components' do
expect(Version.new('1.2.3.0.0').components(2)).to eq([1, 2])
end
it 'can return array filled with zeroes if needed' do
expect(Version.new('1.2.3').components(5)).to eq([1, 2, 3, 0, 0])
end
it 'does not modify version' do
ver = Version.new('1.2.3')
string_version = ver.to_s
expect(ver.components(5)).to eq([1, 2, 3, 0, 0])
expect(ver.to_s).to eq(string_version)
end
end
describe '#Range' do
describe '#include?' do
it 'can check with Version objects' do
range = Version::Range.new(Version.new('1'), Version.new('2'))
vers = Version.new('1.5')
vers1 = Version.new('4.5')
expect(range.include?(vers)).to eq(true)
expect(range.include?(vers1)).to eq(false)
end
it 'can check with Version objects and strings' do
range = Version::Range.new(Version.new('1'), Version.new('2'))
range1 = Version::Range.new('1', Version.new('2'))
range2 = Version::Range.new(Version.new('1'), '2')
vers = Version.new('1.5')
vers1 = Version.new('2.5')
expect(range.include?('1.5')).to eq(true)
expect(range1.include?('1.5')).to eq(true)
expect(range2.include?('1.5')).to eq(true)
expect(range.include?('2.5')).to eq(false)
expect(range1.include?('2.5')).to eq(false)
expect(range2.include?('2.5')).to eq(false)
expect(range1.include?(vers)).to eq(true)
expect(range2.include?(vers)).to eq(true)
expect(range1.include?(vers1)).to eq(false)
expect(range2.include?(vers1)).to eq(false)
end
it 'can check with strings' do
range = Version::Range.new('1', '2')
expect(range.include?('1.5')).to eq(true)
expect(range.include?('3.5')).to eq(false)
end
end
describe '#to_a' do
it 'returns all versions in the range' do
arr = Version::Range.new(
Version.new('1.1.0'), Version.new('1.1.3')
).to_a
arr1 = Version::Range.new(
Version.new('1.0.9'), Version.new('1.2.2')
).to_a
expect(arr).to eq(['1.1.0', '1.1.1', '1.1.2'])
expect(arr1).to eq(
[
'1.0.9', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5',
'1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.2.0', '1.2.1'
]
)
end
end
end
end

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

..........F.F...F..

Failures:

  1) spec Version tests that #components cannot be used to modify the version
     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
             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)
               (@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-1a5myjd/spec.rb:456: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 constructing ranges with strings
     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 = start_version
               @end_version   = 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-1a5myjd/spec.rb:479: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 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-1a5myjd/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)>'

Finished in 19.93 seconds
19 examples, 3 failures

Failed examples:

rspec /tmp/d20161119-19072-1a5myjd/spec.rb:441 # spec Version tests that #components cannot be used to modify the version
rspec /tmp/d20161119-19072-1a5myjd/spec.rb:471 # spec Version::Range tests constructing ranges with strings
rspec /tmp/d20161119-19072-1a5myjd/spec.rb:515 # spec Version::Range tests include? with versions lower than the start one

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

Момчил обнови решението на 18.11.2016 23:12 (преди над 1 година)

+RSpec.describe 'Version' do
+ describe '#Version' do
+ it 'can raise ArgumentError if invalid argument is given' do
+ expect { Version.new('1.1.5') }.to_not raise_error
+
+ expect { Version.new('1.1.5.a') }.to raise_error(
+ ArgumentError, "Invalid version string '1.1.5.a'"
+ )
+
+ expect { Version.new('.1.5') }.to raise_error(
+ ArgumentError, "Invalid version string '.1.5'"
+ )
+
+ expect { Version.new('1..5') }.to raise_error(
+ ArgumentError, "Invalid version string '1..5'"
+ )
+
+ expect { Version.new('1.1.5.') }.to raise_error(
+ ArgumentError, "Invalid version string '1.1.5.'"
+ )
+ end
+ end
+
+ describe '#<=>' do
+ it 'can do <=>' do
+ vers1 = Version.new('1.1.5')
+ vers2 = Version.new('1.1.6')
+ vers3 = Version.new('1.1.6')
+
+ expect(vers1 <=> vers2).to eq(-1)
+ expect(vers2 <=> vers3).to eq(0)
+ expect(vers2 <=> vers1).to eq(1)
+ end
+
+ it 'can do <' do
+ vers1 = Version.new('1.1.5')
+ vers2 = Version.new('1.1.6')
+ vers3 = Version.new('1.1.6')
+
+ expect(vers1 < vers2).to eq(true)
+ expect(vers2 < vers3).to eq(false)
+ expect(vers2 < vers1).to eq(false)
+ end
+
+ it 'can do >' do
+ vers1 = Version.new('1.1.5')
+ vers2 = Version.new('1.1.6')
+ vers3 = Version.new('1.1.6')
+
+ expect(vers1 > vers2).to eq(false)
+ expect(vers2 > vers3).to eq(false)
+ expect(vers2 > vers1).to eq(true)
+ end
+
+ it 'can do <=' do
+ vers1 = Version.new('1.1.5')
+ vers2 = Version.new('1.1.6')
+ vers3 = Version.new('1.1.6')
+
+ expect(vers1 <= vers2).to eq(true)
+ expect(vers2 <= vers3).to eq(true)
+ expect(vers2 <= vers1).to eq(false)
+ end
+
+ it 'can do >=' do
+ vers1 = Version.new('1.1.5')
+ vers2 = Version.new('1.1.6')
+ vers3 = Version.new('1.1.6')
+
+ expect(vers1 >= vers2).to eq(false)
+ expect(vers2 >= vers3).to eq(true)
+ expect(vers2 >= vers1).to eq(true)
+ end
+
+ it 'can do ==' do
+ vers1 = Version.new('1.1.5.0')
+ vers2 = Version.new('1.1.5')
+ vers3 = Version.new('1.5.5')
+ vers4 = Version.new('1.1.5')
+
+ expect(vers1 == vers2).to eq(true)
+ expect(vers2 == vers4).to eq(true)
+ expect(vers1 == vers3).to eq(false)
+ end
+ end
+
+ describe '#to_s' do
+ it 'can show the version as a string' do
+ expect(Version.new('1.2.3').to_s).to eq('1.2.3')
+ end
+
+ it 'can show the version as a string without zeroes at the end' do
+ expect(Version.new('1.2.3.0.0.0').to_s).to eq('1.2.3')
+ end
+
+ it 'can show the version as a string without parameter' do
+ expect(Version.new.to_s).to eq('')
+ end
+
+ it 'can show the version as a string with empty string parameter' do
+ expect(Version.new('').to_s).to eq('')
+ expect(Version.new('0').to_s).to eq('')
+ end
+ end
+
+ describe '#components' do
+ it 'can return array of the components' do
+ expect(Version.new('1.2.3').components).to eq([1, 2, 3])
+ end
+
+ it 'can return array of the components without meaningless zeroes' do
+ expect(Version.new('1.2.3.0.0').components).to eq([1, 2, 3])
+ end
+
+ it 'can return array with exact number of components' do
+ expect(Version.new('1.2.3.0.0').components(2)).to eq([1, 2])
+ end
+
+ it 'can return array filled with zeroes if needed' do
+ expect(Version.new('1.2.3').components(5)).to eq([1, 2, 3, 0, 0])
+ end
+
+ it 'does not modify version' do
+ ver = Version.new('1.2.3')
+ string_version = ver.to_s
+
+ expect(ver.components(5)).to eq([1, 2, 3, 0, 0])
+ expect(ver.to_s).to eq(string_version)
+ end
+ end
+
+ describe '#Range' do
+ describe '#include?' do
+ it 'can check with Version objects' do
+ range = Version::Range.new(Version.new('1'), Version.new('2'))
+ vers = Version.new('1.5')
+ vers1 = Version.new('4.5')
+
+ expect(range.include?(vers)).to eq(true)
+ expect(range.include?(vers1)).to eq(false)
+ end
+
+ it 'can check with Version objects and strings' do
+ range = Version::Range.new(Version.new('1'), Version.new('2'))
+ range1 = Version::Range.new('1', Version.new('2'))
+ range2 = Version::Range.new(Version.new('1'), '2')
+ vers = Version.new('1.5')
+ vers1 = Version.new('2.5')
+
+ expect(range.include?('1.5')).to eq(true)
+ expect(range1.include?('1.5')).to eq(true)
+ expect(range2.include?('1.5')).to eq(true)
+ expect(range.include?('2.5')).to eq(false)
+ expect(range1.include?('2.5')).to eq(false)
+ expect(range2.include?('2.5')).to eq(false)
+ expect(range1.include?(vers)).to eq(true)
+ expect(range2.include?(vers)).to eq(true)
+ expect(range1.include?(vers1)).to eq(false)
+ expect(range2.include?(vers1)).to eq(false)
+ end
+
+ it 'can check with strings' do
+ range = Version::Range.new('1', '2')
+
+ expect(range.include?('1.5')).to eq(true)
+ expect(range.include?('3.5')).to eq(false)
+ end
+ end
+
+ describe '#to_a' do
+ it 'returns all versions in the range' do
+ arr = Version::Range.new(
+ Version.new('1.1.0'), Version.new('1.1.3')
+ ).to_a
+ arr1 = Version::Range.new(
+ Version.new('1.0.9'), Version.new('1.2.2')
+ ).to_a
+
+ expect(arr).to eq(['1.1.0', '1.1.1', '1.1.2'])
+ expect(arr1).to eq(
+ [
+ '1.0.9', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5',
+ '1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.2.0', '1.2.1'
+ ]
+ )
+ end
+ end
+ end
+end