Permalink
Browse files

Merge branch '1.4'

  • Loading branch information...
2 parents a4b3be1 + 98ac314 commit 67a363ff5de702bc7b6a3e5f3d7eef2f3e0fa864 @marick committed May 1, 2012
@@ -0,0 +1,8 @@
+(ns ^{:doc "Customizable configuration"}
+ midje.config)
+
+(def ^{:dynamic true
+ :doc "some doc here"}
+ *allow-default-prerequisites* false)
+
+
@@ -23,6 +23,7 @@
[midje.error-handling.exceptions :only [user-error]]
[midje.internal-ideas.wrapping :only [with-wrapping-target]]
[midje.ideas.arrow-symbols]
+ [midje.config :only [*allow-default-prerequisites*]]
[clojure.tools.macro :only [macrolet]])
(:require [clojure.zip :as zip])
(:import midje.ideas.metaconstants.Metaconstant))
@@ -164,12 +165,13 @@
(defn usable-default-function? [fake]
- (and (bound? (:var fake))
- (let [value-in-var (var-get (:var fake))
- unfinished-fun (:midje/unfinished-fun (meta (:var fake)))]
- (and (extended-fn? value-in-var)
- (or (nil? unfinished-fun)
- (not= unfinished-fun value-in-var))))))
+ (and *allow-default-prerequisites*
+ (bound? (:var fake))
+ (let [value-in-var (var-get (:var fake))
+ unfinished-fun (:midje/unfinished-fun (meta (:var fake)))]
+ (and (extended-fn? value-in-var)
+ (or (nil? unfinished-fun)
+ (not= unfinished-fun value-in-var))))))
;; Used for IFn interface
(def #^:private ^{:testable true}
@@ -0,0 +1,138 @@
+(ns as-documentation.t-prerequisites
+ (:use midje.sweet
+ midje.util
+ midje.test-util))
+
+;; One development path is to work top-down and use the `provided`
+;; clause to substitute prerequisite values.
+
+(unfinished lower-function)
+
+(defn top-function [n]
+ (+ (lower-function n) (lower-function (inc n))))
+
+(fact
+ (top-function 5) => 55
+ (provided
+ (lower-function 5) => 50
+ (lower-function 6) => 5))
+
+;; If you leave off a prerequisite, you get a helpful failure:
+
+(capturing-output
+ (fact
+ (top-function 5) => 55
+ (provided
+ ;; (lower-function 5) => 50 ; omit this one.
+ (lower-function 6) => 5))
+ ;; So...
+ (fact
+ @test-output => #"You never said lower-function would be needed with these arguments:"
+ @test-output => #"\(5\)"))
+
+
+;; You also get a helpful failure for an unused prerequisite:
+
+(capturing-output
+ (fact
+ (top-function 5) => 5555
+ (provided
+ (lower-function 3) => 5000 ; unused
+ (lower-function 4) => 500 ; unused
+ (lower-function 5) => 50 ; omit this one.
+ (lower-function 6) => 5))
+ ;; So...
+ (fact
+ @test-output => #"These calls were not made the right number of times:"
+ @test-output => #"\(lower-function 3\) \[expected at least once, actually never called\]"
+ @test-output => #"\(lower-function 4\) \[expected at least once, actually never called\]"
+ ;; You also get a message about the failure:
+ @test-output => #"Expected: 5555"
+ @test-output => #"Actual: 55"))
+
+
+;; By default, prerequisites can be called one or more times. The
+;; :times modifier lets you change that. Here's how you can insist
+;; a prerequisite be called twice:
+
+(capturing-output
+ (fact
+ (top-function 5) => 55
+ (provided
+ (lower-function 5) => 50 :times 2
+ (lower-function 6) => 5))
+ ;; So...
+ (fact
+ @test-output => #"\(lower-function 5\) \[expected :times 2, actually called one time\]"))
+
+; You can also give a range of allowed values. Here's how you'd ask
+; for a function to be called one or two times:
+
+(after-silently
+ (fact
+ (top-function 5) => 55
+ (provided
+ (lower-function 5) => 50 :times [1 2]
+ (lower-function 6) => 5))
+ (fact
+ @reported => (just pass)))
+
+;; You can also use a lazy sequence:
+
+(after-silently
+ (fact
+ (top-function 5) => 55
+ (provided
+ (lower-function 5) => 50 :times (range 3 33)
+ (lower-function 6) => 5))
+ (fact
+ @reported => (just wrong-call-count
+ pass))) ;; It does give the right answer, for the wrong reason.
+
+
+;; Here is the idiom for "this call is optional" (zero or more times)
+
+(after-silently
+ (fact
+ (top-function 5) => 55
+ (provided
+ (lower-function 0) => 88 :times (range)
+ (lower-function 5) => 50
+ (lower-function 6) => 5))
+ (fact
+ @reported => (just pass)))
+
+
+;;; Default prerequisites
+
+;; Sometimes the prerequisite function already exists. What should
+;; happen if there's no prerequisite for a particular argument list?
+;; Should it default to the existing function or not? The Midje users
+;; who care prefer that such a case be an error:
+
+(defn I-am-I-cried [n] n)
+
+(defn using-function [n]
+ (+ (I-am-I-cried n) (I-am-I-cried (inc n))))
+
+(after-silently
+ (fact
+ (using-function 4) => (+ 80 4)
+ (provided
+ (I-am-I-cried 5) => 80))
+ (fact
+ @reported => (contains no-matching-prerequisite bad-result)))
+
+;; However, it's also possible to ask that unmatched calls default to
+;; the real values:
+
+(binding [midje.config/*allow-default-prerequisites* true]
+
+ (after-silently
+ (fact
+ (using-function 4) => (+ 80 4)
+ (provided
+ (I-am-I-cried 5) => 80))
+ (fact
+ @reported => (just pass))))
+
@@ -3,7 +3,7 @@
(:use [clojure.test])
(:use [midje.test-util]))
-
+(binding [midje.config/*allow-default-prerequisites* false]
(defn f [n] n)
(def position-1 9)
@@ -110,9 +110,8 @@
(name (favorite-animal)) => "betsy"))
(fact
@reported => (just [
- ;; This used to produce a :mock-argument-match-failure because of
- ;; (name "fred"). Since the name function actually exists, it's
- ;; used.
+ (contains {:type :mock-argument-match-failure
+ :position ["t_line_number_reporting.clj" (+ line-number 5)]})
(contains {:type :mock-incorrect-call-count
:failures (just [(contains {:position ["t_line_number_reporting.clj" (+ line-number 5)]
:expected-call "(name ...favorite-animal-value-1...)"})
@@ -131,14 +130,14 @@
(name (favorite-animal 2)) => "jake")) ;; a folded prerequisite can have two errors.
(fact
@reported => (just [(contains {:type :mock-incorrect-call-count
- :failures (just [(contains {:position ["t_line_number_reporting.clj" (+ line-number 6)]
+ :failures (just [(contains {:position ["t_line_number_reporting.clj" (+ line-number 5)]
:expected-call "(name ...favorite-animal-value-2...)"})
- (contains {:position ["t_line_number_reporting.clj" (+ line-number 6)]
+ (contains {:position ["t_line_number_reporting.clj" (+ line-number 5)]
:expected-call "(favorite-animal 2)"}) ])})
pass]))))
- (def line-number-separate 141)
+ (def line-number-separate 140)
(unfinished outermost middlemost innermost)
(in-separate-namespace
(background (outermost) => 2)
@@ -158,18 +157,18 @@
;; future facts
(after-silently
(future-fact "text")
- (fact @reported => (just (contains {:position '("t_line_number_reporting.clj" 160)
+ (fact @reported => (just (contains {:position '("t_line_number_reporting.clj" 159)
:description ["text"] }))))
(after-silently
(pending-fact (+ 1 1) => 2)
- (fact @reported => (just (contains {:position '("t_line_number_reporting.clj" 165)
+ (fact @reported => (just (contains {:position '("t_line_number_reporting.clj" 164)
:description [nil] }))))
;; Improved error handling for pathological cases
-(def line-number-pathological 172)
+(def line-number-pathological 171)
;; statements without lists guess 1+ most recent"
(after-silently
(fact
@@ -198,7 +197,7 @@
(+ line-number-pathological 23)]})])))
-(def facts-position 201)
+(def facts-position 200)
(after-silently
(facts "... also use fallback line number"
1 => even?
@@ -218,7 +217,7 @@
;; Line number reporting for variant expect arrows
-(def variant-position 221)
+(def variant-position 220)
(after-silently
(fact
(+ 1 1) =deny=> 2
@@ -232,7 +231,7 @@
(+ variant-position 5)]}))))
-(def tabular-position 235)
+(def tabular-position 234)
(after-silently
(tabular
(fact (inc ?n) => ?n)
@@ -246,3 +245,4 @@
(contains {:position ["t_line_number_reporting.clj"
(+ tabular-position 3)]
:binding-note "[?n 2\n ?comment \"2\"]"}))))
+)
Oops, something went wrong. Retry.

0 comments on commit 67a363f

Please sign in to comment.