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

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

Към профила на Беатрис Бонева

Резултати

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

Код

RSpec.describe Version do
describe '#new' do
it 'creates an instance from valid version string' do
expect { Version.new('1.1.5') }.to_not raise_error
expect(Version.new('0.2')).to be_instance_of(Version)
end
it 'creates an instance with no parameters' do
expect { Version.new }.to_not raise_error
end
it 'creates an instance from empty string' do
expect { Version.new('') }.to_not raise_error
end
it 'creates an instance from another Version instance' do
expect { Version.new(Version.new('')) }.to_not raise_error
expect { Version.new(Version.new('1')) }.to_not raise_error
expect { Version.new(Version.new('2.0')) }.to_not raise_error
end
it 'raises error for invalid argument' do
expect { Version.new('a.b.c') }.to raise_error(ArgumentError)
expect { Version.new('baba') }.to raise_error(ArgumentError)
expect { Version.new(true) }.to raise_error(ArgumentError)
expect { Version.new([]) }.to raise_error(ArgumentError)
end
it 'raises error with proper message for invalid version string' do
msg = "Invalid version string '.1'"
expect { Version.new('.1') }.to raise_error(ArgumentError, msg)
msg = "Invalid version string '0.1.2.'"
expect { Version.new('0.1.2.') }.to raise_error(ArgumentError, msg)
msg = "Invalid version string '2..1'"
expect { Version.new('2..1') }.to raise_error(ArgumentError, msg)
end
end
describe '#to_s' do
it 'returns the version string' do
expect(Version.new('1.1.5').to_s).to eql('1.1.5')
expect(Version.new('0.1').to_s).to eql('0.1')
end
it 'does not show 0 components at the end' do
expect(Version.new('1.1.0').to_s).to eql('1.1')
expect(Version.new('1.0.0').to_s).to eql('1')
end
end
describe '#>' do
it 'checks if the first version is greater than the second one' do
expect(Version.new('1.1.0') > Version.new('1')).to be true
expect(Version.new('1.1.2') > Version.new('1.1.3')).to be false
v1 = Version.new('1.3.1')
v2 = v1
expect(v1 > v2).to be false
end
end
describe '#>=' do
it 'checks if the first version is greater or equal than the second one' do
expect(Version.new('1.0.1') >= Version.new('1')).to be true
expect(Version.new('4.3.5') >= Version.new('5')).to be false
v1 = Version.new('1.3.1')
v2 = v1
expect(v1 >= v2).to be true
end
end
describe '#<' do
it 'checks if the first version is less than the second one' do
expect(Version.new('1.1.0') < Version.new('1')).to be false
expect(Version.new('1.1.2') < Version.new('1.1.3')).to be true
v1 = Version.new('1.3.1')
expect(v1 < Version.new('1.3.1')).to be false
end
end
describe '#<=' do
it 'checks if the first version is less than or equal to the second one' do
expect(Version.new('1.1.0') <= Version.new('1')).to be false
expect(Version.new('1.1.2') <= Version.new('1.1.3')).to be true
v1 = Version.new('1.3.1')
expect(v1 <= Version.new('1.3.1')).to be true
end
end
describe '#==' do
it 'checks if the two versions are equal' do
v1 = Version.new('5.3.1')
expect(v1 == Version.new('5.3.1')).to be true
expect(Version.new('1.1.0') == Version.new('1.1')).to be true
expect(Version.new('1.1.2') == Version.new('1.1.3')).to be false
expect(Version.new('0.1.2') == Version.new('0.2.1.0')).to be false
end
end
describe '#<=>' do
it 'returns if the first is less than, greater than or equals the second' do
v1 = Version.new('5.3.1')
expect(v1 <=> Version.new('5.3.1')).to be 0
expect(Version.new('1.1.0') <=> Version.new('1.1')).to be 0
expect(Version.new('1.1.2') <=> Version.new('1.1.3')).to be -1
expect(Version.new('2') <=> Version.new('0.2.1')).to be 1
end
end
describe '#components' do
it 'returns the components of the version' do
expect(Version.new('').components).to match_array []
expect(Version.new('1.1.2').components).to match_array [1, 1, 2]
end
it 'ignores 0 components at the end' do
expect(Version.new('3.2.1.0').components).to match_array [3, 2, 1]
expect(Version.new('3.0.0').components).to match_array [3]
end
it 'handles optional argument for the number of components wanted' do
expect(Version.new('3.2.1').components(N = 1)).to match_array [3]
expect(Version.new('0.1.2').components(3)).to match_array [0, 1, 2]
expect(Version.new('2').components(2)).to match_array [2, 0]
end
it 'does not modify the version' do
v1 = Version.new('0.1.2')
v1.freeze
expect { v1.components }.to_not raise_error
end
end
describe "Range" do
describe '#new' do
it 'creates an instance from valid Version objects' do
expect { Version::Range.new(Version.new, Version.new) }
.to_not raise_error
expect { Version::Range.new(Version.new('1.1.5'), Version.new('1.3')) }
.to_not raise_error
expect { Version::Range.new(Version.new('3'), Version.new('1')) }
.to_not raise_error
end
it 'creates an instance from valid version strings' do
expect { Version::Range.new('0.1', '1.3.5') }.to_not raise_error
expect { Version::Range.new('3.2.1', '1.2.3') }.to_not raise_error
end
it 'raises error for invalid version string' do
expect { Version::Range.new('a.b.c', '1') }
.to raise_error(ArgumentError)
expect { Version::Range.new(Version.new('1.2.3'), 'baba') }
.to raise_error(ArgumentError)
expect { Version::Range.new(0, true) }.to raise_error(ArgumentError)
end
it 'raises error with proper message for invalid version string' do
msg = "Invalid version string '.1'"
expect { Version::Range.new('5.6.7', '.1') }
.to raise_error(ArgumentError, msg)
end
end
describe '#include?' do
before(:each) do
@from_1_to_3 = Version::Range.new('1', '3')
end
it 'checks if the given version is in the range' do
expect(@from_1_to_3.include?('1.5')).to be true
expect(@from_1_to_3.include?('1.5.0')).to be true
expect(@from_1_to_3.include?(Version.new('2.5.6'))).to be true
expect(@from_1_to_3.include?(Version.new('3.0'))).to be false
expect(@from_1_to_3.include?('3')).to be false
expect(@from_1_to_3.include?('1.0.0')).to be true
expect(@from_1_to_3.include?('0.0')).to be false
expect(@from_1_to_3.include?(Version.new)).to be false
end
it 'handles invalid version strings' do
expect { @from_1_to_3.include? 'a.b.c' }.to raise_error(ArgumentError)
end
end
describe '#to_a' do
it 'generates all versions from the beginning to the end' do
range = Version::Range.new('1.1.0', '1.2')
expect(range.map(&:to_s)).to match_array(
[
'1.1', '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'
]
)
end
end
end
end

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

..........F......FF

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-4i603h/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 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-4i603h/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)>'

  3) 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-4i603h/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.62 seconds
19 examples, 3 failures

Failed examples:

rspec /tmp/d20161119-19072-4i603h/spec.rb:441 # spec Version tests that #components cannot be used to modify the version
rspec /tmp/d20161119-19072-4i603h/spec.rb:525 # spec Version::Range smoke-tests #to_a
rspec /tmp/d20161119-19072-4i603h/spec.rb:535 # spec Version::Range tests each #to_a element

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

Беатрис обнови решението на 18.11.2016 20:35 (преди над 7 години)

+RSpec.describe Version do
+ describe '#new' do
+ it 'creates an instance from valid version string' do
+ expect { Version.new('1.1.5') }.to_not raise_error
+ expect(Version.new('0.2')).to be_instance_of(Version)
+ end
+ it 'creates an instance with no parameters' do
+ expect { Version.new }.to_not raise_error
+ end
+ it 'creates an instance from empty string' do
+ expect { Version.new('') }.to_not raise_error
+ end
+ it 'creates an instance from another Version instance' do
+ expect { Version.new(Version.new('')) }.to_not raise_error
+ expect { Version.new(Version.new('1')) }.to_not raise_error
+ expect { Version.new(Version.new('2.0')) }.to_not raise_error
+ end
+ it 'raises error for invalid argument' do
+ expect { Version.new('a.b.c') }.to raise_error(ArgumentError)
+ expect { Version.new('baba') }.to raise_error(ArgumentError)
+ expect { Version.new(true) }.to raise_error(ArgumentError)
+ expect { Version.new([]) }.to raise_error(ArgumentError)
+ end
+ it 'raises error with proper message for invalid version string' do
+ msg = "Invalid version string '.1'"
+ expect { Version.new('.1') }.to raise_error(ArgumentError, msg)
+ msg = "Invalid version string '0.1.2.'"
+ expect { Version.new('0.1.2.') }.to raise_error(ArgumentError, msg)
+ msg = "Invalid version string '2..1'"
+ expect { Version.new('2..1') }.to raise_error(ArgumentError, msg)
+ end
+ end
+
+ describe '#to_s' do
+ it 'returns the version string' do
+ expect(Version.new('1.1.5').to_s).to eql('1.1.5')
+ expect(Version.new('0.1').to_s).to eql('0.1')
+ end
+ it 'does not show 0 components at the end' do
+ expect(Version.new('1.1.0').to_s).to eql('1.1')
+ expect(Version.new('1.0.0').to_s).to eql('1')
+ end
+ end
+
+ describe '#>' do
+ it 'checks if the first version is greater than the second one' do
+ expect(Version.new('1.1.0') > Version.new('1')).to be true
+ expect(Version.new('1.1.2') > Version.new('1.1.3')).to be false
+ v1 = Version.new('1.3.1')
+ v2 = v1
+ expect(v1 > v2).to be false
+ end
+ end
+
+ describe '#>=' do
+ it 'checks if the first version is greater or equal than the second one' do
+ expect(Version.new('1.0.1') >= Version.new('1')).to be true
+ expect(Version.new('4.3.5') >= Version.new('5')).to be false
+ v1 = Version.new('1.3.1')
+ v2 = v1
+ expect(v1 >= v2).to be true
+ end
+ end
+
+ describe '#<' do
+ it 'checks if the first version is less than the second one' do
+ expect(Version.new('1.1.0') < Version.new('1')).to be false
+ expect(Version.new('1.1.2') < Version.new('1.1.3')).to be true
+ v1 = Version.new('1.3.1')
+ expect(v1 < Version.new('1.3.1')).to be false
+ end
+ end
+
+ describe '#<=' do
+ it 'checks if the first version is less than or equal to the second one' do
+ expect(Version.new('1.1.0') <= Version.new('1')).to be false
+ expect(Version.new('1.1.2') <= Version.new('1.1.3')).to be true
+ v1 = Version.new('1.3.1')
+ expect(v1 <= Version.new('1.3.1')).to be true
+ end
+ end
+
+ describe '#==' do
+ it 'checks if the two versions are equal' do
+ v1 = Version.new('5.3.1')
+ expect(v1 == Version.new('5.3.1')).to be true
+ expect(Version.new('1.1.0') == Version.new('1.1')).to be true
+ expect(Version.new('1.1.2') == Version.new('1.1.3')).to be false
+ expect(Version.new('0.1.2') == Version.new('0.2.1.0')).to be false
+ end
+ end
+
+ describe '#<=>' do
+ it 'returns if the first is less than, greater than or equals the second' do
+ v1 = Version.new('5.3.1')
+ expect(v1 <=> Version.new('5.3.1')).to be 0
+ expect(Version.new('1.1.0') <=> Version.new('1.1')).to be 0
+ expect(Version.new('1.1.2') <=> Version.new('1.1.3')).to be -1
+ expect(Version.new('2') <=> Version.new('0.2.1')).to be 1
+ end
+ end
+
+ describe '#components' do
+ it 'returns the components of the version' do
+ expect(Version.new('').components).to match_array []
+ expect(Version.new('1.1.2').components).to match_array [1, 1, 2]
+ end
+ it 'ignores 0 components at the end' do
+ expect(Version.new('3.2.1.0').components).to match_array [3, 2, 1]
+ expect(Version.new('3.0.0').components).to match_array [3]
+ end
+ it 'handles optional argument for the number of components wanted' do
+ expect(Version.new('3.2.1').components(N = 1)).to match_array [3]
+ expect(Version.new('0.1.2').components(3)).to match_array [0, 1, 2]
+ expect(Version.new('2').components(2)).to match_array [2, 0]
+ end
+ it 'does not modify the version' do
+ v1 = Version.new('0.1.2')
+ v1.freeze
+ expect { v1.components }.to_not raise_error
+ end
+ end
+
+ describe "Range" do
+ describe '#new' do
+ it 'creates an instance from valid Version objects' do
+ expect { Version::Range.new(Version.new, Version.new) }
+ .to_not raise_error
+ expect { Version::Range.new(Version.new('1.1.5'), Version.new('1.3')) }
+ .to_not raise_error
+ expect { Version::Range.new(Version.new('3'), Version.new('1')) }
+ .to_not raise_error
+ end
+ it 'creates an instance from valid version strings' do
+ expect { Version::Range.new('0.1', '1.3.5') }.to_not raise_error
+ expect { Version::Range.new('3.2.1', '1.2.3') }.to_not raise_error
+ end
+ it 'raises error for invalid version string' do
+ expect { Version::Range.new('a.b.c', '1') }
+ .to raise_error(ArgumentError)
+ expect { Version::Range.new(Version.new('1.2.3'), 'baba') }
+ .to raise_error(ArgumentError)
+ expect { Version::Range.new(0, true) }.to raise_error(ArgumentError)
+ end
+ it 'raises error with proper message for invalid version string' do
+ msg = "Invalid version string '.1'"
+ expect { Version::Range.new('5.6.7', '.1') }
+ .to raise_error(ArgumentError, msg)
+ end
+ end
+
+ describe '#include?' do
+ before(:each) do
+ @from_1_to_3 = Version::Range.new('1', '3')
+ end
+
+ it 'checks if the given version is in the range' do
+ expect(@from_1_to_3.include?('1.5')).to be true
+ expect(@from_1_to_3.include?('1.5.0')).to be true
+ expect(@from_1_to_3.include?(Version.new('2.5.6'))).to be true
+ expect(@from_1_to_3.include?(Version.new('3.0'))).to be false
+ expect(@from_1_to_3.include?('3')).to be false
+ expect(@from_1_to_3.include?('1.0.0')).to be true
+ expect(@from_1_to_3.include?('0.0')).to be false
+ expect(@from_1_to_3.include?(Version.new)).to be false
+ end
+
+ it 'handles invalid version strings' do
+ expect { @from_1_to_3.include? 'a.b.c' }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe '#to_a' do
+ it 'generates all versions from the beginning to the end' do
+ range = Version::Range.new('1.1.0', '1.2')
+ expect(range.map(&:to_s)).to match_array(
+ [
+ '1.1', '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'
+ ]
+ )
+ end
+ end
+ end
+end