Решение на Четвърта задача - Unit тестване от Мариян Асенов
Резултати
- 5 точки от тестове
- 0 бонус точки
- 5 точки общо
- 15 успешни тест(а)
- 4 неуспешни тест(а)
Код
Лог от изпълнението
...FF.F.....F...... Failures: 1) spec Version checks that initialize can be given an empty string 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 /\A[0-9]+(\.[0-9]+)*\z/.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-1z0v1z6/spec.rb:295: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 checks that initialize can be given no arguments 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) (@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-1z0v1z6/spec.rb:314: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 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-1z0v1z6/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)>' 4) 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-1z0v1z6/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)>' Finished in 16.37 seconds 19 examples, 4 failures Failed examples: rspec /tmp/d20161119-19072-1z0v1z6/spec.rb:279 # spec Version checks that initialize can be given an empty string rspec /tmp/d20161119-19072-1z0v1z6/spec.rb:298 # spec Version checks that initialize can be given no arguments rspec /tmp/d20161119-19072-1z0v1z6/spec.rb:353 # spec Version checks for comparison operators negatively rspec /tmp/d20161119-19072-1z0v1z6/spec.rb:471 # spec Version::Range tests constructing ranges with strings
История (8 версии и 16 коментара)
Мариян обнови решението на 17.11.2016 15:05 (преди над 8 години)
Тези две променливи защо са ти?
Разделяй тези блокове с по един празен ред. Ще изглежда много по-прегледно.
Каква е разликата между match_array
и eq
?
Това очевидно няма да промени нищо. Махни .dup
от имплементацията на components
и виж какво може да се случи.
Това подравняване е изключително гадно. И преди да кажеш "Rubocop ме накара", виж следното:
expect(
Version::Range.new(Version.new('1'), Version.new('2')).include?(Version.new('0.9')
).to be false
или по-добре, изкарай една променлива за range-а и използвай .to_not include
вместо .to be false
Моля те, махни тази скоба, защото подсъзнателно искам да ти отнема точка само заради нея.
expect(array_of_versions).to match_array [
Version.new('1.1.0'),
Version.new('1.1.1'),
Version.new('1.1.2')
]
Мариян обнови решението на 17.11.2016 17:13 (преди над 8 години)
Оставих я втората променлива, защото стават повече от 80 символа, ако сложа стринга като аргумент на raise_error
Мариян обнови решението на 17.11.2016 17:46 (преди над 8 години)
expect { Version.new(0..2) }.to raise_error(
ArgumentError,
"Invalid version string '0..2'"
)
Не разбирам този тест какво прави тук.
Ами мислех си, че трябва да проверяваме дали #to_s не променя обекта.
Мариян обнови решението на 17.11.2016 19:59 (преди над 8 години)
Кое те наведе на тази мисъл?
Тоест не е проблем и да променя обекта и да не тествам за този случай? Тъй като в условието на задачата не е споменато дали го променя или не
Тоест не е проблем и да променя обекта и да не тествам за този случай? Тъй като в условието на задачата не е споменато дали го променя или не
Тоест не е проблем и да променя обекта и да не тествам за този случай? Тъй като в условието на задачата не е споменато дали го променя или не
В другия метод ако не се внимава - може да се промени обектът. Тук няма реална опасност да стане това. Не се връща нищо свързано със състоянието на версията.
Просто няма логика някога това да се счупи. Иначе, предполагам не би тествал дали <
, >
, <=
, >=
, ==
, <=>
, Version::Range.new
и всички останали методи променят обекта. Защо тогава да тестваш само този?
Добре съгласих се!