Кузман обнови решението на 12.11.2016 17:24 (преди над 8 години)
+RSpec.describe 'Version' do
+ describe '#new' do
+ context 'correct versioning' do
+ it 'creates version "" object if no version spesified' do
+ expect(Version.new.to_s).to eq ''
+ end
+
+ it 'creates version "" object if initialized with blank object' do
+ expect(Version.new(Version.new).to_s).to eq ''
+ end
+
+ it 'creates version "" object if initialized with empty string' do
+ expect(Version.new('').to_s).to eq ''
+ end
+
+ it 'creates correct version with zeroed prefixes' do
+ expect(Version.new('00000.01.002.0003.00004').to_s).to eq '0.1.2.3.4'
+ end
+
+ it 'creates correct version with zeroed suffixes' do
+ expect(Version.new('00000.01.002.0003.00000.0000').to_s).to eq '0.1.2.3'
+ end
+
+ it 'can be initialized with Version object' do
+ expect(Version.new(Version.new('9.01.2.3.004')).to_s).to eq '9.1.2.3.4'
+ end
+ end
+
+ context 'errors' do
+ it 'raises ArgumentError if initialized with bad string' do
+ v = '0..1'
+ expect { Version.new(v) }.to raise_error(ArgumentError)
+ end
+
+ it 'raises error with correct error message if initialized badly' do
+ v = '0..1'
+ err = "Invalid version string '#{v}'"
+ expect { Version.new(v) }.to raise_error(err)
+ end
+
+ it 'raises error if last separator separates nothing' do
+ v = '0.1.'
+ err = "Invalid version string '#{v}'"
+ expect { Version.new(v) }.to raise_error(ArgumentError, err)
+ end
+
+ it 'raises ArgumentError if initialized with bad characters' do
+ bad_chars = "`~!@#$%^&*()-_=+ []{}\\|;:\'\",<.>/?\n\t\s"
+ bad_chars.each_char.all? do |c|
+ v = "1.2.1#{c}.3"
+ err = "Invalid version string '#{v}'"
+ expect { Version.new(v) }.to raise_error(ArgumentError, err)
+ end
+ end
+ end
+ end
+
+ describe "#<=> a.k.a. comparissons" do
+ context 'correct comparissons' do
+ it 'correctly compares zeroed versions with eq' do
+ expect(Version.new('1')).to eq Version.new('1.0.0.0.0')
+ end
+
+ it 'correctly compares not initialized versions' do
+ expect(Version.new).to be < Version.new('0.0.0.0.0.0.0.0.0.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality <' do
+ expect(Version.new('1')).to be < Version.new('1.0.0.0.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality >' do
+ expect(Version.new('1.1')).to be > Version.new('1.0.0.0.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality <=' do
+ expect(Version.new('1.0.0.1')).to be <= Version.new('1.0.0.1.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality >=' do
+ expect(Version.new('1.0.0.1.2')).to be >= Version.new('1.0.0.1.0.0.1')
+ end
+
+ it 'correctly compares new versions with <=' do
+ expect(Version.new).to be <= Version.new
+ end
+
+ it 'correctly compares new versions with >=' do
+ expect(Version.new).to be >= Version.new
+ end
+
+ it 'correctly compares new versions with eq' do
+ expect(Version.new).to eq Version.new
+ end
+ end
+
+ context 'incorrect comparissons' do
+ it 'correctly compares zeroed versions with not_to eq' do
+ expect(Version.new('1')).not_to eq Version.new('1.0.0.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality >' do
+ expect(Version.new('1')).not_to be > Version.new('1.0.0.0.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality <' do
+ expect(Version.new('1.1')).not_to be < Version.new('1.0.0.0.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality >' do
+ expect(Version.new('1.0.0.1')).not_to be > Version.new('1.0.0.1.0.0.1')
+ end
+
+ it 'correctly compares zeroed versions with inequality <' do
+ expect(Version.new('1.0.0.1.2')).not_to be < Version.new('1.0.0.1.0.1')
+ end
+
+ it 'correctly compares new versions with >' do
+ expect(Version.new).not_to be > Version.new
+ end
+
+ it 'correctly compares new versions with <' do
+ expect(Version.new).not_to be < Version.new
+ end
+ end
+ end
+
+ describe "#to_s" do
+ context 'correct stringification' do
+ it 'stringifies with no parameters correctly' do
+ expect(Version.new.to_s).to be_an_instance_of(String)
+ end
+
+ it 'stringifies with with parameters correctly' do
+ expect(Version.new('1.2.3.4.5').to_s).to be_an_instance_of(String)
+ end
+
+ it 'stringifies with with version parameters correctly' do
+ expect(Version.new(Version.new('1')).to_s).to be_an_instance_of(String)
+ end
+
+ it 'correcly stringifies zeroed versions' do
+ expect(Version.new('1.1.0.0.0.0.0.0').to_s).to eq '1.1'
+ end
+
+ it 'correcly stringifies non-zeroed versions' do
+ expect(Version.new('1.1.0.0.0.0.0.1.2').to_s).to eq '1.1.0.0.0.0.0.1.2'
+ end
+ end
+
+ context 'incorrect stringification' do
+ it 'stringifies correctly zeroed versions' do
+ expect(Version.new('1.1.0.0.0.0.0.0').to_s).not_to eq '1.1.0.0.0.0.0.0'
+ end
+
+ it 'stringifies correctly zeroed prefixes versions' do
+ expect(Version.new('1.01.00.0.0.0.0').to_s).not_to eq '1.01.00.0.0.0.0'
+ end
+ end
+ end
+
+ describe '#components' do
+ context 'correct componentification' do
+ it 'returns an array' do
+ v = '1.01.00.00.0000.00.00.01.02.00.00000.0'
+ expect(Version.new(v).components).to be_an_instance_of(Array)
+ end
+
+ it 'correctly componentifies versions' do
+ v = '1.01.00.00.0000.00.00.01.02.00.00000.0'
+ arr = [1, 1, 0, 0, 0, 0, 0, 1, 2]
+ expect(Version.new(v).components).to match_array(arr)
+ end
+
+ it 'returns correct components with parameter less than total size' do
+ v = '1.01.00.00.0000.00.00.01.02.00.00000.0'
+ arr = [1, 1, 0, 0, 0]
+ expect(Version.new(v).components(5)).to match_array(arr)
+ end
+
+ it 'returns correct components with parameter more than total size' do
+ v = '1.01.00.00.0000.1.2.3'
+ arr = [1, 1, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0]
+ expect(Version.new(v).components(12)).to match_array(arr)
+ end
+
+ it 'does not change the version componenting with less than the size' do
+ v = '1.01.00.00.0000.00.00.01.02.00.00000.0'
+ ver = Version.new(v)
+ ver.components(5)
+ expect(ver.to_s).to eq '1.1.0.0.0.0.0.1.2'
+ end
+
+ it 'does not change the version componenting with more than the size' do
+ v = '1.01.00.00.0000.00.00.01.02.00.00000.0'
+ ver = Version.new(v)
+ ver.components(23)
+ expect(ver.to_s).to eq '1.1.0.0.0.0.0.1.2'
+ end
+ end
+ context 'incorrect componentification' do
+ it 'correctly componentifies versions' do
+ v = '1.01.00.00.0000.00.00.01.02.00.00000.0'
+ arr = [1, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0]
+ expect(Version.new(v).components).not_to match_array(arr)
+ end
+ end
+ end
+
+ describe 'Range' do
+ describe "#new" do
+ context 'errors' do
+ it 'cannot create Version::Range with one string parameter' do
+ expect { Version::Range.new('3') }.to raise_error(ArgumentError)
+ end
+
+ it 'cannot create Version::Range with one Version parameter' do
+ expect { Version::Range.new(Version.new('4')) }
+ .to raise_error(ArgumentError)
+ end
+ end
+
+ context 'create with strings and versions' do
+ it 'can create Range from Version and String mixtures' do
+ array = ['3', '4', Version.new('5'), Version.new('6')]
Това е антипатърн - старай се да използваш възможно най-малко код (логика) в тестовете. Изпиши си случаите един по един. Няма да стане по-дълго, а ще е очевидно какво се тества.
+ array.combination(2).to_a.each.all? do |first, second|
+ v = Version::Range.new(first, second)
+ expect(v.include?(Version.new((first.to_s.to_i + 0.5).to_s)))
+ .to be true
+ end
+ end
+ end
+ end
+
+ describe '#include?' do
+ context 'inclusions' do
+ it 'can correctly check inclusions' do
+ range = Version::Range.new('1.10.11', '2.9.31')
+ versions = [
+ '1.10.011', '1.011', '1.10.11', '1.099.01',
+ '2.0', '2.9.30.999', '2.09.030', '02.02.02'
+ ]
+ versions.each.all? do |ver|
-
.each.all?
? - Отново, изпиши си проверките една по една. Недей да въртиш цикли в тестовете.
+ v = Version.new(ver)
+ expect(range.include?(v)).to be true
+ end
+ end
+ end
+
+ context 'non-inclusions' do
+ it 'can correctly check non-inclusions' do
+ range = Version::Range.new('1.10.11', '2.9.31')
+ versions = [
+ '1.10.010.9999', '0.1.11', '2.9.031', '0.2.9.0',
+ '2.9.40', '2.9.0310', '10.10.10', '02.09.31'
+ ]
+ versions.each.all? do |ver|
+ v = Version.new(ver)
+ expect(range.include?(v)).to eq false
+ end
+ end
+ end
+ end
+
+ describe '#to_a' do
+ context 'creating valid arrays' do
+ it 'can create an array from Version::Range' do
+ arr = (290...301).to_a.map do |i|
+ Version.new(i.to_s.reverse.to_i.to_s.reverse.split(//).join("."))
+ end
arr = (290...301).to_a.map do |i|
Version.new(i.to_s.reverse.to_i.to_s.reverse.split(//).join("."))
end
vs
['2.9', '2.9.1', '2.9.2', '2.9.3', '2.9.4', '2.9.5', '2.9.6', '2.9.7', '2.9.8', '2.9.9', '3']
Кое се чете по-лесно? :)
+ expect(Version::Range.new('2.9', '3.0.1').to_a).to match_array(arr)
+ end
+
+ it 'creates empty array if start value is greater than end value' do
+ arr = []
+ expect(Version::Range.new('9.9', '3.0.1').to_a).to match_array(arr)
+ end
+
+ it 'creates empty array if start value is equal to end value' do
+ arr = []
+ expect(Version::Range.new('9.9', '9.9').to_a).to match_array(arr)
+ end
+ end
+ end
+ end
+end
Като цяло, целта на задачата е да се сетиш за всички гранични случаи и да ги опишеш в RSpec :) Не ти трябват цикли, не ти трябват условни конструкции - просто едно изреждане на възможни случаи. За тестовете възможно най-тъпия код е най-добър, защото е очевидно какво се пита и какво се очаква като резултат.
Представяй си тестовете като примери от условието на задачата.