Skip to content

Commit

Permalink
pending specs are reported in progress reporter
Browse files Browse the repository at this point in the history
  • Loading branch information
slagyr committed May 15, 2011
1 parent 5c8655e commit 9913477
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 69 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ It's a TDD/BDD framework for [Clojure](http://clojure.org/), based on [RSpec](ht
# Installation

## With Leiningen
You will need [Leiningen][https://github.com/technomancy/leiningen] version 1.4 or later.
You will need [Leiningen](https://github.com/technomancy/leiningen) version 1.4 or later.

Include speclj in your `:dev-dependencies` and change the `:test-path` to `"spec/"`

Expand Down
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Features to add

* around-all and with-all components
* pending examples (examples without any body)
* tag examples. declared in describe blocks. filtered on run.
* exclude hidden files in runs (https://github.com/slagyr/speclj/pull/4)
Expand Down
66 changes: 40 additions & 26 deletions spec/speclj/report/progress_spec.clj
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
(ns speclj.report.progress-spec
(:use
[speclj.core]
[speclj.report.progress :only (new-progress-reporter full-name print-summary)]
[speclj.report.progress :only (new-progress-reporter full-name print-summary print-pendings)]
[speclj.reporting]
[speclj.exec :only (pass-result fail-result pending-result)]
[speclj.components :only (new-description new-characteristic install)]
[speclj.config :only (*color?*)]
[clojure.string :only (split-lines)])
(:import
[speclj SpecFailure]
[speclj SpecFailure SpecPending]
[java.io ByteArrayOutputStream OutputStreamWriter]))

(defn to-s [output]
Expand Down Expand Up @@ -60,12 +60,11 @@
results [result1 result2 result3]
_ (report-runs @reporter results)
lines (split-lines (to-s @output))]
(should= 5 (count lines))
(should= 4 (count lines))
(should= "" (lines 0))
(should= "" (lines 1))
(should= "Finished in 0.12300 seconds" (lines 2))
(should= "" (lines 3))
(should= (green "3 examples, 0 failures") (lines 4)))))
(should= (green "3 examples, 0 failures") (lines 3)))))

(it "reports failing run results"
(binding [*color?* true]
Expand All @@ -79,42 +78,57 @@
results [result1 result2 result3]
_ (report-runs @reporter results)
lines (split-lines (to-s @output))]
(should= 20 (count lines))
(should= 18 (count lines))
(should= "" (lines 0))
(should= "" (lines 1))
(should= "1)" (lines 2))
(should= (red "'Crazy flips' FAILED") (lines 3))
(should= (red "Expected flips") (lines 4))
; (should= "/Users/micahmartin/Projects/clojure/speclj/spec/speclj/report/progress_spec.clj:67" (lines 5))
(should= "" (lines 6))
(should= "2)" (lines 7))
(should= (red "'Crazy spins' FAILED") (lines 8))
(should= (red "Expected spins") (lines 9))
(should= "Failures:" (lines 2))
(should= "" (lines 3))
(should= " 1) Crazy flips" (lines 4))
(should= (red " Expected flips") (lines 5))
; (should= "/Users/micahmartin/Projects/clojure/speclj/spec/speclj/report/progress_spec.clj:67" (lines 6))
(should= "" (lines 7))
(should= " 2) Crazy spins" (lines 8))
(should= (red " Expected spins") (lines 9))
; (should= "/Users/micahmartin/Projects/clojure/speclj/spec/speclj/report/progress_spec.clj:55" (lines 10))
(should= "" (lines 11))
(should= "3)" (lines 12))
(should= (red "'Crazy dives' FAILED") (lines 13))
(should= (red "Expected dives") (lines 14))
; (should= "/Users/micahmartin/Projects/clojure/speclj/spec/speclj/report/progress_spec.clj:56" (lines 15))
(should= "" (lines 16))
(should= "Finished in 0.32100 seconds" (lines 17))
(should= "" (lines 18))
(should= (red "3 examples, 3 failures") (lines 19)))))
(should= " 3) Crazy dives" (lines 12))
(should= (red " Expected dives") (lines 13))
; (should= "/Users/micahmartin/Projects/clojure/speclj/spec/speclj/report/progress_spec.clj:56" (lines 14))
(should= "" (lines 15))
(should= "Finished in 0.32100 seconds" (lines 16))
(should= (red "3 examples, 3 failures") (lines 17)))))

(it "reports pending run results"
(binding [*color?* true]
(let [result1 (pass-result nil 0.1)
result2 (pass-result nil 0.02)
result3 (pending-result nil 0.003)
(let [description (new-description "Crazy" *ns*)
char1 (new-characteristic "flips" description "flip")
result1 (pass-result char1 0.1)
result2 (pass-result char1 0.02)
result3 (pending-result char1 0.003 (SpecPending. "Blah"))
results [result1 result2 result3]
_ (print-summary results)
lines (split-lines (to-s @output))]
(should= (yellow "3 examples, 0 failures, 1 pending") (last lines)))))

(it "reports pending summary"
(let [description (new-description "Crazy" *ns*)
char1 (new-characteristic "flips" description "flip")
result1 (pending-result char1 0.3 (SpecPending. "Not Yet Implemented"))
_ (print-pendings [result1])
lines (split-lines (to-s @output))]
(should= 6 (count lines))
(should= "" (nth lines 0))
(should= "Pending:" (nth lines 1))
(should= "" (nth lines 2))
(should= (yellow " Crazy flips") (nth lines 3))
(should= (grey " ; Not Yet Implemented") (nth lines 4))
; (should= (grey " ; /Users/micahmartin/Projects/clojure/speclj/spec/speclj/report/progress_spec.clj:117") (nth lines 5))
))

(it "can calculate the full name of a characteristic"
(let [outer (new-description "Outer" *ns*)
inner (new-description "Inner" *ns*)
char (new-characteristic "char" inner "char")]
(throw (Exception. "Fooey!"))
(install inner outer)
(should= "Outer Inner char" (full-name char))))
)
Expand Down
15 changes: 15 additions & 0 deletions spec/speclj/reporting_spec.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
(it "prints in green"
(should= "\u001b[32mtext\u001b[0m" (green "text")))

(it "prints in yellow"
(should= "\u001b[33mtext\u001b[0m" (yellow "text")))

(it "prints in grey"
(should= "\u001b[90mtext\u001b[0m" (grey "text")))
)
Expand Down Expand Up @@ -75,6 +78,18 @@ Caused by: java.lang.Exception: Cause
]))
(print-stack-trace exception output)
(should= expected (.toString output))))

(it "prefixes lines of text"
(should= "--foo" (prefix "--" "foo"))
(should= "++bar" (prefix "++" "bar"))
(should= "=foobar" (prefix "=" "foo" "bar"))
(should= "--foo\n--bar" (prefix "--" "foo\nbar")))

(it "can indent"
(should= " foo" (indent 2 "foo"))
(should= " bar" (indent 4 "bar"))
(should= " foo\n bar" (indent 2 "foo\nbar"))
(should= " foo\n bar" (indent 4 "foo\nbar")))
)
)

Expand Down
9 changes: 9 additions & 0 deletions speclj.iml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/fresh-1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

9 changes: 9 additions & 0 deletions src/speclj/SpecPending.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package speclj;

public class SpecPending extends Exception
{
public SpecPending(String s)
{
super(s);
}
}
6 changes: 3 additions & 3 deletions src/speclj/exec.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

(deftype PassResult [characteristic seconds])
(deftype FailResult [characteristic seconds failure])
(deftype PendingResult [characteristic seconds])
(deftype PendingResult [characteristic seconds exception])

(defn pass-result [characteristic seconds]
(PassResult. characteristic seconds))

(defn fail-result [characteristic seconds failure]
(FailResult. characteristic seconds failure))

(defn pending-result [characteristic seconds]
(PendingResult. characteristic seconds))
(defn pending-result [characteristic seconds exception]
(PendingResult. characteristic seconds exception))

(defmulti pass? type)
(defmethod pass? PassResult [result] true)
Expand Down
81 changes: 46 additions & 35 deletions src/speclj/report/progress.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(ns speclj.report.progress
(:use
[speclj.reporting :only (failure-source tally-time red green yellow print-stack-trace)]
[speclj.reporting :only (failure-source tally-time red green yellow grey stack-trace indent prefix)]
[speclj.exec :only (pass? fail? pending?)]
[speclj.util :only (seconds-format)]
[speclj.config :only (default-reporter)])
Expand All @@ -18,61 +18,71 @@
(let [characteristic (.characteristic result)
failure (.failure result)]
(println)
(println (str id ")"))
(println (red (str "'" (full-name characteristic) "' FAILED")))
(println (red (.getMessage failure)))
(println (indent 2 id ") " (full-name characteristic)))
(println (red (indent 5 (.getMessage failure))))
(if (.isInstance SpecFailure failure)
(println (failure-source failure))
(print-stack-trace failure *out*)
)))
(println (grey (indent 5 "; " (failure-source failure))))
(println (grey (indent 5 (prefix "; " (stack-trace failure))))))))

(defn print-failures [results]
(println)
(let [failures (vec (filter fail? results))]
(dotimes [i (count failures)]
(print-failure (inc i) (nth failures i)))))
(defn print-failures [failures]
(when (seq failures)
(println)
(println "Failures:"))
(dotimes [i (count failures)]
(print-failure (inc i) (nth failures i))))

(defn print-pendings [pending-results]
(when (seq pending-results)
(println)
(println "Pending:"))
(doseq [result pending-results]
(println)
(println (yellow (str " " (full-name (.characteristic result)))))
(println (grey (str " ; " (.getMessage (.exception result)))))
(println (grey (str " ; " (failure-source (.exception result)))))))

(defn- print-duration [results]
(println)
(println "Finished in" (.format seconds-format (tally-time results)) "seconds"))

(defn- tally [results]
(defn- categorize [results]
(reduce (fn [tally result]
(cond (pending? result) (update-in tally [:pending] inc)
(fail? result) (update-in tally [:fail] inc)
:else (update-in tally [:pass] inc)))
{:pending 0 :fail 0 :pass 0}
results))
(cond (pending? result) (update-in tally [:pending] conj result)
(fail? result) (update-in tally [:fail] conj result)
:else (update-in tally [:pass] conj result)))
{:pending [] :fail [] :pass []}
results))

(defn color-fn-for [tally]
(cond (not= 0 (:fail tally)) red
(not= 0 (:pending tally)) yellow
:else green))
(defn color-fn-for [result-map]
(cond (not= 0 (count (:fail result-map))) red
(not= 0 (count (:pending result-map))) yellow
:else green))

(defn- describe-counts-for [tally]
(let [always-on-counts [(str (apply + (vals tally)) " examples")
(defn- describe-counts-for [result-map]
(let [tally (apply hash-map (interleave (keys result-map) (map count (vals result-map))))
always-on-counts [(str (apply + (vals tally)) " examples")
(str (:fail tally) " failures")]]
(apply str
(interpose ", "
(if (> (:pending tally) 0)
(conj always-on-counts (str (:pending tally) " pending"))
always-on-counts)))))
(conj always-on-counts (str (:pending tally) " pending"))
always-on-counts)))))

(defn- print-tally [results]
(println)
(let [tally (tally results)
color-fn (color-fn-for tally)]
(println (color-fn (describe-counts-for tally)))))
(defn- print-tally [result-map]
(let [color-fn (color-fn-for result-map)]
(println (color-fn (describe-counts-for result-map)))))

(defn print-summary [results]
(print-failures results)
(print-duration results)
(print-tally results))
(let [result-map (categorize results)]
(print-failures (:fail result-map))
(print-pendings (:pending result-map))
(print-duration results)
(print-tally result-map)))

(deftype ProgressReporter []
Reporter
(report-message [this message]
(println message)(flush))
(println message) (flush))
(report-description [this description])
(report-pass [this result]
(print (green ".")) (flush))
Expand All @@ -81,6 +91,7 @@
(report-fail [this result]
(print (red "F")) (flush))
(report-runs [this results]
(println)
(print-summary results)))

(defn new-progress-reporter []
Expand Down
26 changes: 23 additions & 3 deletions src/speclj/reporting.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
(:use
[speclj.exec :only (pass? fail?)]
[speclj.config :only (*reporter* *color?* *full-stack-trace?*)]
[clojure.string :as string :only (split)])
(:import [speclj.exec PassResult FailResult PendingResult]))
[clojure.string :as string :only (split join)])
(:import
[speclj.exec PassResult FailResult PendingResult]
[java.io PrintWriter StringWriter]))

(defn- classname->filename [classname]
(let [root-name (first (split classname #"\$"))]
Expand Down Expand Up @@ -86,9 +88,27 @@
(println (.toString exception)))
(print-stack-levels exception))

(defn stack-trace [exception]
(let [output (StringWriter.)]
(binding [*out* (PrintWriter. output)]
(if *full-stack-trace?*
(.printStackTrace exception *out*)
(print-exception nil exception)))
(.toString output)))

(defn print-stack-trace [exception writer]
(if *full-stack-trace?*
(.printStackTrace exception (java.io.PrintWriter. writer))
(.printStackTrace exception (PrintWriter. writer))
(binding [*out* writer]
(print-exception nil exception))))

(defn prefix [pre & args]
(let [value (apply str args)
lines (split value #"[\r\n]+")
prefixed-lines (map #(str pre %) lines)]
(join (System/getProperty "line.separator") prefixed-lines)))

(defn indent [n & args]
(let [indention (reduce (fn [p _] (str " " p)) "" (range n))]
(apply prefix indention args)))

3 changes: 2 additions & 1 deletion src/speclj/running.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
[speclj.util :only (secs-since)]
[speclj.config :only (*runner* active-reporter)])
(:import
[speclj SpecPending]
[java.io File]))

(defn- eval-components [components]
Expand Down Expand Up @@ -50,7 +51,7 @@
start-time (System/nanoTime)]
(try
(if (.pending characteristic)
(report-result pending-result characteristic start-time reporter nil)
(report-result pending-result characteristic start-time reporter (SpecPending. "Not Yet Implemented"))
(do
(full-body)
(report-result pass-result characteristic start-time reporter nil)))
Expand Down

0 comments on commit 9913477

Please sign in to comment.