Class: Hegel::Generator::Filtered

Inherits:
Generator
  • Object
show all
Defined in:
lib/hegel/generator.rb,
sig/hegel.rbs

Overview

Generator#filter's result. Retries the source generator, each attempt in its own span, up to MAX_ATTEMPTS times before discarding the test case (Hegel::AssumeFailed) -- the same budget hegel-rust's Filtered spends before calling assume(false) (src/generators/generators.rs), ported here rather than reinvented so a predicate that (almost) never holds fails the same way in both bindings.

A predicate that never holds does not loop forever: libhegel's own health check aborts a run that discards too many test cases in a row, which Hegel::Runner.finish surfaces as Hegel::Error, the same path an engine-level failure takes for any other reason.

Constant Summary collapse

MAX_ATTEMPTS =

Returns:

  • (Integer)
3

Instance Method Summary collapse

Constructor Details

#initialize(source, block) ⇒ Filtered

Returns a new instance of Filtered.

Parameters:



75
76
77
78
79
# File 'lib/hegel/generator.rb', line 75

def initialize(source, block)
  super()
  @source = source
  @block = block
end

Instance Method Details

#do_draw(tc) ⇒ Object

Parameters:

  • tc (Object)

Returns:

  • (Object)

Raises:



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/hegel/generator.rb', line 81

def do_draw(tc)
  MAX_ATTEMPTS.times do
    accepted = false
    value = nil
    tc.start_span(LibHegel::HEGEL_LABEL_FILTER)
    begin
      value = @source.do_draw(tc)
      accepted = @block.call(value)
    ensure
      tc.stop_span(discard: !accepted)
    end
    return value if accepted
  end
  raise Hegel::AssumeFailed
end