lib/prop_check/property.rb in prop_check-0.10.0 vs lib/prop_check/property.rb in prop_check-0.10.1

- old
+ new

@@ -1,9 +1,11 @@ require 'stringio' require "awesome_print" require 'prop_check/property/configuration' +require 'prop_check/property/output_formatter' +require 'prop_check/property/shrinker' require 'prop_check/hooks' module PropCheck ## # Run properties class Property @@ -110,20 +112,43 @@ end self end + ## + # Calls `hook` before each time a check is run with new data. + # + # This is useful to add setup logic + # When called multiple times, earlier-added hooks will be called _before_ `hook` is called. def before(&hook) @hooks.add_before(&hook) self end + ## + # Calls `hook` after each time a check is run with new data. + # + # This is useful to add teardown logic + # When called multiple times, earlier-added hooks will be called _after_ `hook` is called. def after(&hook) @hooks.add_after(&hook) self end + ## + # Calls `hook` around each time a check is run with new data. + # + # `hook` should `yield` to the passed block. + # + # When called multiple times, earlier-added hooks will be wrapped _around_ `hook`. + # + # Around hooks will be called after all `#before` hooks + # and before all `#after` hooks. + # + # Note that if the block passed to `hook` raises an exception, + # it is possible for the code after `yield` not to be called. + # So make sure that cleanup logic is wrapped with the `ensure` keyword. def around(&hook) @hooks.add_around(&hook) self end @@ -221,85 +246,17 @@ end end private def show_problem_output(problem, generator_results, n_successful, &block) output = @config.verbose ? STDOUT : StringIO.new - output = pre_output(output, n_successful, generator_results.root, problem) + output = PropCheck::Property::OutputFormatter.pre_output(output, n_successful, generator_results.root, problem) shrunken_result, shrunken_exception, n_shrink_steps = shrink(generator_results, output, &block) - output = post_output(output, n_shrink_steps, shrunken_result, shrunken_exception) + output = PropCheck::Property::OutputFormatter.post_output(output, n_shrink_steps, shrunken_result, shrunken_exception) [output, shrunken_result, shrunken_exception, n_shrink_steps] end - private def pre_output(output, n_successful, generated_root, problem) - output.puts "" - output.puts "(after #{n_successful} successful property test runs)" - output.puts "Failed on: " - output.puts "`#{print_roots(generated_root)}`" - output.puts "" - output.puts "Exception message:\n---\n#{problem}" - output.puts "---" - output.puts "" - - output - end - - private def post_output(output, n_shrink_steps, shrunken_result, shrunken_exception) - if n_shrink_steps == 0 - output.puts '(shrinking impossible)' - else - output.puts '' - output.puts "Shrunken input (after #{n_shrink_steps} shrink steps):" - output.puts "`#{print_roots(shrunken_result)}`" - output.puts "" - output.puts "Shrunken exception:\n---\n#{shrunken_exception}" - output.puts "---" - output.puts "" - end - output - end - - private def print_roots(lazy_tree_val) - if lazy_tree_val.is_a?(Array) && lazy_tree_val.length == 1 && lazy_tree_val[0].is_a?(Hash) - lazy_tree_val[0].ai - else - lazy_tree_val.ai - end - end - private def shrink(bindings_tree, io, &block) - io.puts 'Shrinking...' if @config.verbose - problem_child = bindings_tree - siblings = problem_child.children.lazy - parent_siblings = nil - problem_exception = nil - shrink_steps = 0 - @hooks.wrap_enum(0..@config.max_shrink_steps).lazy.each do - begin - sibling = siblings.next - rescue StopIteration - break if parent_siblings.nil? - - siblings = parent_siblings.lazy - parent_siblings = nil - next - end - - shrink_steps += 1 - io.print '.' if @config.verbose - - begin - block.call(*sibling.root) - rescue Exception => e - problem_child = sibling - parent_siblings = siblings - siblings = problem_child.children.lazy - problem_exception = e - end - end - - io.puts "(Note: Exceeded #{@config.max_shrink_steps} shrinking steps, the maximum.)" if shrink_steps >= @config.max_shrink_steps - - [problem_child.root, problem_exception, shrink_steps] + PropCheck::Property::Shrinker.call(bindings_tree, io, @hooks, @config, &block) end end end