lib/speculation/spec/f_spec.rb in speculation-0.3.1 vs lib/speculation/spec/f_spec.rb in speculation-0.4.0

- old
+ new

@@ -1,20 +1,25 @@ # frozen_string_literal: true +# This is a Ruby translation of clojure.spec: +# https://github.com/clojure/clojure/blob/master/src/clj/clojure/spec.clj +# All credit belongs with Rich Hickey and contributors for their original work. + module Speculation # @private class FSpec < Spec include NamespacedSymbols S = Speculation attr_reader :args, :ret, :fn, :block - def initialize(args: nil, ret: nil, fn: nil, block: nil) - @args = args - @ret = ret - @fn = fn + def initialize(args: nil, ret: nil, fn: nil, block: nil, gen: nil) + @args = args + @ret = ret + @fn = fn @block = block + @gen = gen end def conform(f) raise "Can't conform fspec without args spec: #{inspect}" unless @args @@ -54,10 +59,14 @@ cargs = S.conform(@args, args) S.explain1(@fn, Utils.conj(path, :fn), via, inn, :args => cargs, :ret => cret) end end + def with_gen(gen) + self.class.new(:args => @args, :ret => @ret, :fn => @fn, :block => @block, :gen => gen) + end + def gen(overrides, _path, _rmap) return @gen if @gen ->(_rantly) do ->(*args, &block) do @@ -75,21 +84,16 @@ end # @private # returns f if valid, else smallest def self.validate_fn(f, specs, iterations) - args_gen = S.gen(specs[:args]) + args_gen = S.gen(specs[:args]) + block_gen = specs[:block] ? S.gen(specs[:block]) : Utils.constantly(nil) + arg_block_gen = Gen.tuple(args_gen, block_gen) - block_gen = if specs[:block] - S.gen(specs[:block]) - else - Utils.constantly(nil) - end - - combined = ->(r) { [args_gen.call(r), block_gen.call(r)] } - generator_guard = ->(genned_val) { S.valid?(specs[:args], genned_val) } - ret = S::Test.send(:rantly_quick_check, combined, iterations, generator_guard) { |(args, block)| + + ret = S::Test.send(:rantly_quick_check, arg_block_gen, iterations, generator_guard) { |(args, block)| call_valid?(f, specs, args, block) } smallest = ret[:shrunk] && ret[:shrunk][:smallest] smallest || f