   "allows users to dynamically rebind to 1+"
   [n (gen-int #(>= % 1))]
   (binding [*num-trials* n] nil) 
-     =not=> (throws Exception))
-
-
-;;;; Formulas
-
-;; the first formula use ever!
-(defn make-string []
-  (rand-nth ["a" "b" "c" "d" "e" "f" "g" "i"]))
-(formula "can now use simple generative-style formulas - with multiple bindings"
-  [a (make-string) b (make-string) c (make-string)]
-  (str a b c) => (has-prefix (str a b)))
-
-(unfinished f)
-(defn g [x] (str (f x) x))
-
-(formula "'provided' works"
-  [a (make-string)]
-  (g a) => (str "foo" a)
-  (provided 
-    (f anything) => "foo"))
-
-
-;; failed formulas report once per formula regardless how many generations were run
-(after-silently
-  (formula "some description" [a "y"] a => :foo))
-(fact @reported => (one-of (contains {:type :mock-expected-result-failure
-                                      :description "some description"})))
-
-
-;; passing formulas run the generator many times, and evaluate 
-;; their body many times - number of generations is rebindable
-(defn-call-countable y-maker [] "y")
-(defn-call-countable my-str [s] (str s))
-
-(binding [*num-trials* 77]
-  (formula [y (y-maker)]
-    (my-str y) => "y"))
-(fact @y-maker-count => 77)
-(fact @my-str-count => 77)
-
-
-;; can specify number of trials to run in options map - overrides *num-trials* var value
-(defn-call-countable foo-maker [] "foo")
-(defn-call-countable my-double-str [s] (str "double" s))
-
-(binding [*num-trials* 111]  ;; this will be overridden by opt map
-  (formula "asdf" {:num-trials 88} [foo (foo-maker)]
-    (my-double-str foo) => "doublefoo"))
-(fact @foo-maker-count => 88)
-(fact @my-double-str-count => 88)
-
-
-;; runs only as few times as needed to see a failure
-(defn-call-countable z-maker [] "z")
-(defn-call-countable my-identity [x] (identity x))
-
-(after-silently 
-  (formula [z (z-maker)]
-    (my-identity z) => "clearly not 'z'"))
-(fact "calls generator once" @z-maker-count => 1)
-(fact "evalautes body once" @my-identity-count => 1)
-
-;; shrinks failure case to smallest possible failure -- shrinks each binding result
-(when-1-3+
-  (with-redefs [midje.ideas.formulas/shrink (fn [x] 
-                                               (if (integer? x) 
-                                                 [0 1 2 3 4 5]
-                                                 ["a" "b" "c" "d" "e"]))]
-    (after-silently
-      (formula [x 100 a "abc"]
-        [x a] => #(neg? (first %))))
-    (fact @reported => (one-of (contains {:type :mock-expected-result-functional-failure
-                                          :actual [0 "a"]} ))))) ;; note that it shrank both 100 and "abc"
-
-;; shrunken failure case is in the same domain as the generator 
-;; used to create the input case in the first place.
-(after-silently
-  (formula [x (gen-int odd?)]  ;;(guard (gs/int) odd?)] 
-    x => neg?))
-(future-fact "shrunken failure case is in the same domain as the generator" 
-  @reported => (one-of (contains {:type :mock-expected-result-failure
-                                  :actual 1})))
-
-
-;;;; Other
-
-(future-formula "demonstrating the ability to create future formulas"
-  [a 1]
-  a => 1)+     =not=> (throws Exception))
  (k a) => 10)

;; :num-trials can be any number 1+
(formula {:num-trials 1 } [a 1] a => 1)
(formula {:num-trials 2} [a 1] a => 1)
(formula {:num-trials 3} [a 1] a => 1)
(formula {:num-trials 4} [a 1] a => 1)

        midje.util.ecosystem
        [midje.ideas.formulas :only [*num-trials*]] ))


;;;; Formulas

;; First we create our own generator functions since Midje doesn't include any.
(defn make-string []
  (rand-nth ["a" "b" "c" "d" "e" "f" "g" "i"]))
(defn- gen-int [pred]
  (rand-nth (filter pred [-999 -100 -20 -5 -4 -3 -2 -1 0 1 2 3 4 5 20 100 999])))

;; Formulas are a generative style test macro. Each binding has a generator on 
;; the right and a symbol on the left that will hold the generated value

(formula "can now use simple generative-style formulas - with multiple bindings"
  [a (make-string) b (make-string) c (make-string)]
  (str a b c) => (has-prefix (str a b)))

;; You can use provided to make fakes inside of a formula
(unfinished f)
(defn g [x] (str (f x) x))

(formula "'provided' works"
  [a (make-string)]
  (g a) => (str "foo" a)
  (provided 
    (f anything) => "foo"))


;; Failed formulas report once per formula regardless how many trials were run
(after-silently
  (formula "some description" [a "y"] a => :foo))
(fact @reported => (one-of (contains {:type :mock-expected-result-failure
                                      :description "some description"})))


;; Passing formulas run the generator many times, and evaluate 
;; their body many times - number of trials is rebindable
(defn-call-countable y-maker [] "y")
(defn-call-countable my-str [s] (str s))

(binding [*num-trials* 77]
  (formula [y (y-maker)]
    (my-str y) => "y"))
(fact @y-maker-count => 77)
(fact @my-str-count => 77)


;; Can specify number of trials to run in options map - overrides *num-trials* var value
(defn-call-countable foo-maker [] "foo")
(defn-call-countable my-double-str [s] (str "double" s))

(binding [*num-trials* 111]  ;; this will be overridden by opt map
  (formula "asdf" {:num-trials 88} [foo (foo-maker)]
    (my-double-str foo) => "doublefoo"))
(fact @foo-maker-count => 88)
(fact @my-double-str-count => 88)


;; Runs only as few times as needed to see a failure
(defn-call-countable z-maker [] "z")
(defn-call-countable my-identity [x] (identity x))

(after-silently 
  (formula [z (z-maker)]
    (my-identity z) => "clearly not 'z'"))
(fact "calls generator once" @z-maker-count => 1)
(fact "evalautes body once" @my-identity-count => 1)

;; Shrinks failure case to smallest possible failure -- shrinks each binding result
(when-1-3+
  (with-redefs [midje.ideas.formulas/shrink (fn [x] 
                                               (if (integer? x) 
                                                 [0 1 2 3 4 5]
                                                 ["a" "b" "c" "d" "e"]))]
    (after-silently
      (formula [x 100 a "abc"]
        [x a] => #(neg? (first %))))
    (fact @reported => (one-of (contains {:type :mock-expected-result-functional-failure
                                          :actual [0 "a"]} ))))) ;; note that it shrank both 100 and "abc"

;; Shrunken failure case is in the same domain as the generator 
;; used to create the input case in the first place.
(after-silently
  (formula [x (gen-int odd?)]  ;;(guard (gs/int) odd?)] 
    x => neg?))
(future-fact "shrunken failure case is in the same domain as the generator" 
  @reported => (one-of (contains {:type :mock-expected-result-failure
                                  :actual 1})))


;;;; Other

(future-formula "demonstrating the ability to create future formulas"
  [a 1]
  a => 1)
                

;;;; Validation

;; The following facts express an assortment of ways that formulas 
;; could be expressed with invalid syntax

(unfinished h)

