Решение на Четвърта задача - 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 (преди около 9 години)
Не е добра идея да ги преизползваш по този начин, защото се запазват между различните тестове. Ако първия тест счупи някой от обектите, следващия тест ще фейлне.
Виж 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 (преди около 9 години)
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 в тестовете, тъй като наистина е по-четливо.
При теб е проблемът :) Виж какъв обект създаваш
Началната версия е включена в резултата, а крайната - не.
този ред ми беше убягнал! Мерси за насоката.
