lib/rantly/property.rb in rantly-0.3.2 vs lib/rantly/property.rb in rantly-1.0.0
- old
+ new
@@ -4,10 +4,11 @@
class Rantly::Property
attr_reader :failed_data, :shrunk_failed_data, :io
VERBOSITY = ENV.fetch('RANTLY_VERBOSE'){ 1 }.to_i
+ RANTLY_COUNT = ENV.fetch('RANTLY_COUNT'){ 100 }.to_i
def io
@io ||= if VERBOSITY >= 1
STDOUT
else
@@ -21,11 +22,11 @@
def initialize(property)
@property = property
end
- def check(n=100,limit=10,&assertion)
+ def check(n=RANTLY_COUNT,limit=10,&assertion)
i = 0
test_data = nil
begin
Rantly.singleton.generate(n,limit,@property) do |val|
test_data = val
@@ -44,33 +45,42 @@
io.puts
io.puts "failure: #{i} tests, on:"
pretty_print test_data
@failed_data = test_data
if @failed_data.respond_to?(:shrink)
- @shrunk_failed_data = shrinkify(assertion, @failed_data)
- io.puts "minimal failed data is:"
+ @shrunk_failed_data, @depth = shrinkify(assertion, @failed_data)
+ io.puts "minimal failed data (depth #{@depth}) is:"
pretty_print @shrunk_failed_data
end
raise boom
end
end
- # return the first success case
- def shrinkify(assertion, data)
- # We assume that data.shrink is non-destructive
- return data if !data.shrinkable?
- val = data.shrink
- begin
- assertion.call(val)
- io.puts "found a reduced success:"
- pretty_print val
- return data
- rescue Exception
- io.puts "found a reduced failure case:"
- pretty_print val
- # recursively shrink failure case
- return shrinkify(assertion,val)
+ # Explore the failures tree
+ def shrinkify(assertion, data, depth=0, iteration=0)
+ io.puts "Shrinking at depth #{depth}:"
+ pretty_print data
+
+ min_data = data
+ max_depth = depth
+ if data.shrinkable?
+ while iteration < 1024 do
+ # We assume that data.shrink is non-destructive
+ shrunk_data = data.shrink
+ begin
+ assertion.call(shrunk_data)
+ rescue Exception
+ # If the assertion was verified, recursively shrink failure case
+ branch_data, branch_depth, iteration = shrinkify(assertion, shrunk_data, depth + 1, iteration + 1)
+ if branch_depth > max_depth
+ min_data = branch_data
+ max_depth = branch_depth
+ end
+ end
+ break if !data.retry?
+ end
end
+ return min_data, max_depth, iteration
end
def report
distribs = self.classifiers.sort { |a,b| b[1] <=> a[1] }
total = distribs.inject(0) { |sum,pair| sum + pair[1]}