module Minitest::Thesis # Represents some range of values that might be used in a test, that can be # requested from a `TestCase`. Pass one of these to TestCase.any to get a # concrete value. class Possibility attr_reader :produce, :name def initialize(name, &produce) @name = name @produce = produce end def inspect = name def to_s = name # "Returns a `Possibility` where values come from applying `f` to some possible value for `self`." def map(&f) self.class.new("#{name}.map(#{f.class})") {|tc| f.call(tc.any(self)) } end # Returns a `Possibility` where values come from applying `f` (which # should return a new `Possibility` to some possible value for `self` # then returning a possible value from that. def bind(&f) self.class.new("#{name}.bind(#{f.class})") {|tc| tc.any(f.(tc.any(self))) } end # Returns a `Possibility` whose values are any possible value of `self` # for which `f` returns True. def satisfying(&f) self.class.new("#{name}.select(#{f.class})") {|test_case| 3.times.first { candidate = test_case.any(self) candidate if f.(candidate) } || test_case.reject } end end end