lib/rantly/property.rb in rantly-0.3.1 vs lib/rantly/property.rb in rantly-0.3.2
- old
+ new
@@ -1,60 +1,82 @@
require 'rantly'
-require 'test/unit'
require 'pp'
+require 'stringio'
class Rantly::Property
+ attr_reader :failed_data, :shrunk_failed_data, :io
+ VERBOSITY = ENV.fetch('RANTLY_VERBOSE'){ 1 }.to_i
+
+ def io
+ @io ||= if VERBOSITY >= 1
+ STDOUT
+ else
+ StringIO.new
+ end
+ end
+
+ def pretty_print(object)
+ PP.pp(object, io)
+ end
+
def initialize(property)
@property = property
end
-
+
def check(n=100,limit=10,&assertion)
i = 0
test_data = nil
begin
Rantly.singleton.generate(n,limit,@property) do |val|
test_data = val
assertion.call(val) if assertion
- puts "" if i % 100 == 0
- print "." if i % 10 == 0
+ io.puts "" if i % 100 == 0
+ io.print "." if i % 10 == 0
i += 1
end
- puts
- puts "success: #{i} tests"
+ io.puts
+ io.puts "success: #{i} tests"
rescue Rantly::TooManyTries => e
- puts
- puts "too many tries: #{e.tries}"
+ io.puts
+ io.puts "too many tries: #{e.tries}"
raise e
- rescue => boom
- puts
- puts "failure: #{i} tests, on:"
- pp test_data
+ rescue Exception => boom
+ 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:"
+ 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)
+ end
+ end
+
def report
distribs = self.classifiers.sort { |a,b| b[1] <=> a[1] }
total = distribs.inject(0) { |sum,pair| sum + pair[1]}
distribs.each do |(classifier,count)|
format "%10.5f%% of => %s", count, classifier
end
end
-end
-
-module Test::Unit::Assertions
- def property_of(&block)
- Rantly::Property.new(block)
- end
-end
-
-begin
- require 'rspec'
- class RSpec::Core::ExampleGroup
- def property_of(&block)
- Rantly::Property.new(block)
- end
- end
-rescue LoadError
- "No RSpec loaded. Oh, well."
end