class Rantly::Property

Constants

RANTLY_COUNT
VERBOSITY

Attributes

failed_data[R]
shrunk_failed_data[R]

Public Class Methods

new(property) click to toggle source
# File lib/rantly/property.rb, line 23
def initialize(property)
  @property = property
end

Public Instance Methods

check(n = RANTLY_COUNT, limit = 10) { |val| ... } click to toggle source
# File lib/rantly/property.rb, line 27
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
      yield(val) if assertion
      io.puts '' if (i % 100).zero?
      io.print '.' if (i % 10).zero?
      i += 1
    end
    io.puts
    io.puts "SUCCESS - #{i} successful tests"
  rescue Rantly::TooManyTries => e
    io.puts
    io.puts "FAILURE - #{i} successful tests, too many tries: #{e.tries}"
    raise e.exception("#{i} successful tests, too many tries: #{e.tries} (limit: #{e.limit})")
  rescue Exception => boom
    io.puts
    io.puts "FAILURE - #{i} successful tests, failed on:"
    pretty_print test_data
    @failed_data = test_data
    if @failed_data.respond_to?(:shrink)
      @shrunk_failed_data, @depth = shrinkify(assertion, @failed_data)
      io.puts "Minimal failed data (depth #{@depth}) is:"
      pretty_print @shrunk_failed_data
    end
    raise boom.exception("#{i} successful tests, failed on:\n#{test_data}\n\n#{boom}\n")
  end
end
io() click to toggle source
# File lib/rantly/property.rb, line 11
def io
  @io ||= if VERBOSITY >= 1
            STDOUT
          else
            StringIO.new
          end
end
pretty_print(object) click to toggle source
# File lib/rantly/property.rb, line 19
def pretty_print(object)
  PP.pp(object, io)
end
shrinkify(assertion, data, depth = 0, iteration = 0) click to toggle source

Explore the failures tree

# File lib/rantly/property.rb, line 59
def shrinkify(assertion, data, depth = 0, iteration = 0)
  min_data = data
  max_depth = depth
  if data.shrinkable?
    while iteration < 1024
      # 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 unless data.retry?
    end
  end
  [min_data, max_depth, iteration]
end