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