Решение на Четвърта задача - Unit тестване от Иван Станков
Резултати
- 5 точки от тестове
- 0 бонус точки
- 5 точки общо
- 16 успешни тест(а)
- 3 неуспешни тест(а)
Код
Лог от изпълнението
......F...F.......F Failures: 1) spec Version checks for comparison operators negatively Failure/Error: expect(@solution).to_not pass_tests expected this solution to not pass the tests: class Version def >(other) true end 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) (@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-cllt4r/spec.rb:359: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 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-cllt4r/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)>' 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-cllt4r/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 16.22 seconds 19 examples, 3 failures Failed examples: rspec /tmp/d20161119-19072-cllt4r/spec.rb:353 # spec Version checks for comparison operators negatively rspec /tmp/d20161119-19072-cllt4r/spec.rb:441 # spec Version tests that #components cannot be used to modify the version rspec /tmp/d20161119-19072-cllt4r/spec.rb:535 # spec Version::Range tests each #to_a element
История (4 версии и 8 коментара)
Иван обнови решението на 12.11.2016 14:17 (преди над 8 години)
Не е добра идея да ги преизползваш по този начин, защото се запазват между различните тестове. Ако първия тест счупи някой от обектите, следващия тест ще фейлне.
Виж let. let ще инстанцира тези обекти за всеки тест поотделно и няма как да leak-не състоянието от единия тест в другия.
И друго - v1, v2, v3, v4 по принцип не са добри имена, защото при четенето на теста ме караш постоянно да скачам до тези редове, за да проверя какво означават.
Имаш три варианта:
- Да им измислиш по-добри имена. Не съм сигурен колко лесно е в този случай.
- Дублиране на код в тестовете не трябва да те притеснява особено, ако ще ги направи по-прости. Тоест можеш и да си ги copy-paste-неш долу.
- Можеш да си направиш някакъв помощен метод, който да ти спести писането на Version.new
Тук можеш да ползваш .to < нещо
:)
Това е еквивалентно на expect(v2).to eq Version.new('1.2.4')
. В момента правиш (v2 == Version.new('1.2.4')) == true
Иван обнови решението на 13.11.2016 10:41 (преди над 8 години)
Failure/Error:
expect(Range.new(Version.new('1.0.1'), Version.new('1.0.2')).to_a).to eq(
['1.0.1', '1.0.2']
)
TypeError:
can't iterate from Version
Тук все още получавам грешка, дори и при последната версия на version.rb. При мен ли е проблема?
П.П. Благодаря за предишните коментари! Използвах .to be на местата къде мога. #let и другите помощни методи ще ми бъдат от полза, но реших да заменя v1, v2... със Vector.new в тестовете, тъй като наистина е по-четливо.
При теб е проблемът :) Виж какъв обект създаваш
Началната версия е включена в резултата, а крайната - не.
този ред ми беше убягнал! Мерси за насоката.