Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Many fixes.

  • Loading branch information...
commit 33b8263137e02cf75404fa07206e56ea716c77c2 1 parent 505c3d4
@pjstadig authored
Showing with 564 additions and 152 deletions.
  1. +11 −0 .metrics/20110303072014/line-counts.clj
  2. +5 −0 .metrics/20110303072014/unused-names.clj
  3. +11 −0 .metrics/20110303072459/line-counts.clj
  4. +5 −0 .metrics/20110303072459/unused-names.clj
  5. +4 −0 fixtures/line-count/.gitignore
  6. +13 −0 fixtures/line-count/README
  7. +4 −0 fixtures/line-count/project.clj
  8. +1 −0  fixtures/line-count/src/line_count/core.clj
  9. +6 −0 fixtures/line-count/test/line_count/test/core.clj
  10. +4 −0 fixtures/unused-names/.gitignore
  11. +13 −0 fixtures/unused-names/README
  12. +6 −0 fixtures/unused-names/project.clj
  13. +14 −0 fixtures/unused-names/src/unused_names/core.clj
  14. +4 −0 fixtures/unused-names/src/unused_names/example.js
  15. +6 −0 fixtures/unused-names/test/unused_names/test/core.clj
  16. +5 −2 project.clj
  17. +52 −0 src/leiningen/metrics.clj
  18. +135 −32 src/procrustes/code.clj
  19. +59 −0 src/procrustes/file.clj
  20. +29 −0 src/procrustes/line_count.clj
  21. +0 −73 src/procrustes/unused_deps.clj
  22. +64 −0 src/procrustes/unused_names.clj
  23. +84 −25 test/procrustes/test/code.clj
  24. +18 −0 test/procrustes/test/line_count.clj
  25. +0 −20 test/procrustes/test/unused_deps.clj
  26. +11 −0 test/procrustes/test/unused_names.clj
View
11 .metrics/20110303072014/line-counts.clj
@@ -0,0 +1,11 @@
+{:file
+ {:test
+ {"test/procrustes/test/line_count.clj" 17,
+ "test/procrustes/test/code.clj" 96,
+ "test/procrustes/test/unused_names.clj" 10},
+ :src
+ {"src/leiningen/metrics.clj" 44,
+ "src/procrustes/file.clj" 53,
+ "src/procrustes/line_count.clj" 26,
+ "src/procrustes/code.clj" 122,
+ "src/procrustes/unused_names.clj" 58}}}
View
5 .metrics/20110303072014/unused-names.clj
@@ -0,0 +1,5 @@
+{:file
+ {"test/procrustes/test/unused_names.clj" (procrustes.code/read-code),
+ "test/procrustes/test/code.clj"
+ (clojure.java.io/reader clojure.java.io/input-stream),
+ "src/procrustes/line_count.clj" (procrustes.file/common-ancestor)}}
View
11 .metrics/20110303072459/line-counts.clj
@@ -0,0 +1,11 @@
+{:file
+ {:test
+ {"test/procrustes/test/line_count.clj" 17,
+ "test/procrustes/test/code.clj" 96,
+ "test/procrustes/test/unused_names.clj" 10},
+ :src
+ {"src/leiningen/metrics.clj" 46,
+ "src/procrustes/file.clj" 53,
+ "src/procrustes/line_count.clj" 26,
+ "src/procrustes/code.clj" 122,
+ "src/procrustes/unused_names.clj" 58}}}
View
5 .metrics/20110303072459/unused-names.clj
@@ -0,0 +1,5 @@
+{:file
+ {"test/procrustes/test/unused_names.clj" (procrustes.code/read-code),
+ "test/procrustes/test/code.clj"
+ (clojure.java.io/reader clojure.java.io/input-stream),
+ "src/procrustes/line_count.clj" (procrustes.file/common-ancestor)}}
View
4 fixtures/line-count/.gitignore
@@ -0,0 +1,4 @@
+pom.xml
+*jar
+lib
+classes
View
13 fixtures/line-count/README
@@ -0,0 +1,13 @@
+# line-count
+
+FIXME: write description
+
+## Usage
+
+FIXME: write
+
+## License
+
+Copyright (C) 2010 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
View
4 fixtures/line-count/project.clj
@@ -0,0 +1,4 @@
+(defproject line-count "1.0.0-SNAPSHOT"
+ :description "FIXME: write"
+ :dependencies [[org.clojure/clojure "1.2.0"]
+ [org.clojure/clojure-contrib "1.2.0"]])
View
1  fixtures/line-count/src/line_count/core.clj
@@ -0,0 +1 @@
+(ns line-count.core)
View
6 fixtures/line-count/test/line_count/test/core.clj
@@ -0,0 +1,6 @@
+(ns line-count.test.core
+ (:use [line-count.core] :reload)
+ (:use [clojure.test]))
+
+(deftest replace-me ;; FIXME: write
+ (is false "No tests have been written."))
View
4 fixtures/unused-names/.gitignore
@@ -0,0 +1,4 @@
+pom.xml
+*jar
+lib
+classes
View
13 fixtures/unused-names/README
@@ -0,0 +1,13 @@
+# unused-names
+
+FIXME: write description
+
+## Usage
+
+FIXME: write
+
+## License
+
+Copyright (C) 2010 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
View
6 fixtures/unused-names/project.clj
@@ -0,0 +1,6 @@
+(defproject unused-names "1.0.0-SNAPSHOT"
+ :description "FIXME: write"
+ :dependencies [[org.clojure/clojure "1.2.0"]
+ [org.clojure/clojure-contrib "1.2.0"]]
+ :dev-dependencies [[swank-clojure "1.2.1"]
+ [lein-difftest "1.3.1-SNAPSHOT"]])
View
14 fixtures/unused-names/src/unused_names/core.clj
@@ -0,0 +1,14 @@
+(ns unused-names.core
+ (:require [clojure.contrib.combinatorics]
+ [clojure.contrib.str-utils :as stru] :reload-all)
+ (:use [clojure.contrib.jar :only [jar-file?]]
+ [clojure.contrib.graph :only [add-loops]])
+ (:require [clojure.contrib.io]
+ [clojure.contrib.command-line :as cl] :reload)
+ (:use [clojure.contrib.def]))
+
+(defn foo [s]
+ (clojure.contrib.io/file (stru/chop s)))
+
+(defn bar [j]
+ (jar-file? j))
View
4 fixtures/unused-names/src/unused_names/example.js
@@ -0,0 +1,4 @@
+// this is an example js file
+function (x) {
+ return x;
+}
View
6 fixtures/unused-names/test/unused_names/test/core.clj
@@ -0,0 +1,6 @@
+(ns unused-names.test.core
+ (:use [unused-names.core] :reload)
+ (:use [clojure.test]))
+
+(deftest replace-me ;; FIXME: write
+ (is false "No tests have been written."))
View
7 project.clj
@@ -1,7 +1,10 @@
(defproject procrustes "1.0.0-SNAPSHOT"
:description "Metrics for your Clojure code."
:dependencies [[org.clojure/clojure "1.2.0"]
- [org.clojure/clojure-contrib "1.2.0"]]
+ [org.clojure/clojure-contrib "1.2.0"]
+ [robert/hooke "1.0.2"]]
:dev-dependencies [[swank-clojure "1.2.1"]
[lein-difftest "1.3.1-SNAPSHOT"]]
- :hooks [leiningen.hooks.difftest])
+ :eval-in-project true
+ :hooks [leiningen.hooks.difftest
+ leiningen.metrics])
View
52 src/leiningen/metrics.clj
@@ -0,0 +1,52 @@
+(ns leiningen.metrics
+ (:use [clojure.pprint :only [pprint]]
+ [procrustes.line-count :only [line-counts]]
+ [procrustes.unused-names :only [unused-names]]
+ [clojure.java.io :only [file writer]])
+ (:import [java.io PushbackReader]
+ [java.util Date]
+ [java.text SimpleDateFormat]))
+
+(defn- metrics-dir [project]
+ (let [f (file (.getParent (file (:source-path project)))
+ ".metrics"
+ (.format (SimpleDateFormat. "yyyyMMddhhmmss") (Date.)))]
+ (when-not (.exists f)
+ (.mkdirs f))
+ f))
+
+(defn write-metrics [dir metrics]
+ (doseq [[report metric] metrics]
+ (let [path (file dir (str (name report) ".clj"))]
+ (.mkdirs (.getParentFile path))
+ (with-open [f (writer path)]
+ (.write f (with-out-str (pprint metric)))))))
+
+(defn- usage []
+ (println "Try lein metrics line-counts"))
+
+(defn metrics-command [project command args]
+ (let [project-path (file (:source-path project))
+ files (filter #(.endsWith (.getName %) ".clj")
+ (file-seq project-path))]
+ (cond
+ (= "line-counts" command) {:line-counts
+ (line-counts [(:source-path project)]
+ [(:test-path project)])}
+ (= "unused-names" command) {:unused-names
+ (unused-names [(:source-path project)]
+ [(:test-path project)])}
+ (empty? command) {:line-counts (line-counts [(:source-path project)]
+ [(:test-path project)])
+ :unused-names (unused-names [(:source-path project)]
+ [(:test-path project)])}
+ :else (println "Unknown command"))))
+
+(defn gather [project command args]
+ (write-metrics (metrics-dir project)
+ (metrics-command project command args)))
+
+(defn metrics
+ "Gather metrics about your codez."
+ [project & [command & args]]
+ (gather project command args))
View
167 src/procrustes/code.clj
@@ -1,33 +1,136 @@
(ns procrustes.code
- (:use [clojure.java.io :only [reader]])
- (:import [java.io PushbackReader]))
-
-(defn- search-code* [code pred matches]
- (if (pred code)
- (conj matches code)
- (if (and (coll? code)
- (not (empty? code)))
- (mapcat #(search-code* % pred matches) code))))
-
-(defn search-code [code pred]
- (search-code* code pred []))
-
-(defn find-ns-form [code]
- (first (for [x code :when (= 'ns (first x))]
- x)))
-
-(defn find-ns-name [code]
- (second (find-ns-form code)))
-
-(defn but-ns-form [code]
- (for [x code :when (not= 'ns (first x))]
- x))
-
-(defn- read-code* [s code]
- (let [e (read s false ::eof)]
- (if (= ::eof e)
- code
- (recur s (conj code e)))))
-
-(defn read-code [s]
- (read-code* (PushbackReader. (reader s)) []))
+ (:use [clojure.java.io :only [reader file]])
+ (:import (clojure.lang LineNumberingPushbackReader
+ LispReader
+ LispReader$ReaderException
+ IMeta)))
+
+(defn- map-with-meta
+ ([seq]
+ (map-with-meta identity seq))
+ ([f seq]
+ (map (fn [x]
+ (let [y (f x)]
+ (if (and (instance? IMeta y)
+ (empty? (meta y))
+ (or (meta x)
+ (meta seq)))
+ (with-meta y (or (meta x)
+ (meta seq)))
+ y)))
+ seq)))
+
+(defn- mapcat-with-meta
+ ([coll]
+ (mapcat-with-meta identity coll))
+ ([f coll]
+ (reduce concat
+ (map-with-meta (fn [x]
+ (let [x (if (sequential? x)
+ (map-with-meta x)
+ x)
+ y (f x)]
+ (if (meta y)
+ y
+ (with-meta y (meta x))))) coll))))
+
+(defn- rest-with-meta [s]
+ (let [r (rest s)]
+ (if (meta r)
+ r
+ (with-meta r (meta s)))))
+
+(defn search-code
+ ([pred code]
+ (search-code pred code []))
+ ([pred code matches]
+ (if (pred code)
+ (conj matches code)
+ (if (and (coll? code)
+ (not (empty? code)))
+ (mapcat #(search-code pred % matches)
+ (map-with-meta code))))))
+
+(defn application? [name form]
+ (and (list? form) (= name (first form))))
+
+(defn ns? [form]
+ (application? 'ns form))
+
+(defn ns-require-name
+ ([form]
+ (ns-require-name form (first form)))
+ ([form name]
+ (if (seq form)
+ (if (= :as (first form))
+ (fnext form)
+ (recur (rest form) name))
+ name)))
+
+(defn ns-requires [form]
+ {:pre [(ns? form)]}
+ (->> (filter (partial application? :require) form)
+ (mapcat-with-meta rest-with-meta)
+ (remove #{:reload :reload-all})
+ (map-with-meta (fn [r]
+ (if (sequential? r)
+ {(ns-require-name r) (first r)}
+ {r r})))))
+
+(defn ns-use-onlys [form]
+ (if (and (sequential? form)
+ (seq form))
+ (if (= :only (first form))
+ (fnext form)
+ (recur (rest form)))))
+
+(defn ns-uses [form]
+ {:pre [(ns? form)]}
+ (->> (filter (partial application? :use) form)
+ (mapcat-with-meta rest-with-meta)
+ (map-with-meta (fn [u]
+ (if-let [onlys (ns-use-onlys u)]
+ {(first u) onlys})))
+ (filter identity)))
+
+(defn blocks
+ ([code]
+ (if (not (ns? (first code)))
+ (blocks code '[(ns user)] [])
+ (blocks code [] [])))
+ ([code block blocks]
+ (if (seq code)
+ (if (ns? (first code))
+ (recur (rest code) [(first code)] (if (seq block)
+ (conj blocks block)
+ blocks))
+ (recur (rest code) (conj block (first code)) blocks))
+ (if (seq block)
+ (conj blocks block)
+ blocks))))
+
+(defn read-code
+ ([s]
+ (read-code (LineNumberingPushbackReader. (reader s)) []))
+ ([s code]
+ (let [e (LispReader/read s false ::eof false)]
+ (if (= ::eof e)
+ code
+ (recur s (conj code e))))))
+
+(defn unwrap-runtime-exception [e]
+ (if (and (instance? RuntimeException e)
+ (.getCause e))
+ (recur (.getCause e))
+ e))
+
+(defn read-code-from-file [f]
+ (try
+ (read-code (file f))
+ (catch LispReader$ReaderException e
+ (throw (RuntimeException. (str "Error reading " f) e)))
+ (catch RuntimeException e
+ (let [c (unwrap-runtime-exception e)]
+ (if (instance? LispReader$ReaderException c)
+ (throw (RuntimeException. (str "Error reading " f) c))
+ (throw e))))))
View
59 src/procrustes/file.clj
@@ -0,0 +1,59 @@
+(ns procrustes.file
+ (:use [clojure.java.io :only [file]])
+ (:import (java.io File)))
+
+(defn segments->file #^File [segments]
+ (reduce (fn [file s]
+ (File. file s))
+ segments))
+
+(defn file->segments
+ ([#^File file]
+ (file->segments file () (set (File/listRoots))))
+ ([#^File file segments roots]
+ (if (and file (not (roots file)))
+ (recur (.getParentFile file) (conj segments (.getName file)) roots)
+ (conj segments file))))
+
+(defn common-prefix
+ ([[root1 & segments1] [root2 & segments2]]
+ (if (= root1 root2)
+ (common-prefix segments1 segments2 [root1])
+ []))
+ ([[s1 & segments1] [s2 & segments2] result]
+ (if (= s1 s2)
+ (if (and (seq segments1) (seq segments2))
+ (recur segments1 segments2 (conj result s1))
+ (conj result s1))
+ result)))
+
+(defn common-ancestor
+ ([files]
+ (if (empty? files)
+ nil
+ (reduce common-ancestor files)))
+ ([#^File file1 #^File file2]
+ (let [prefix (common-prefix (file->segments file1)
+ (file->segments file2))]
+ (segments->file prefix))))
+
+(defn canonicalize-file [file base]
+ (.replaceAll (.getCanonicalPath file)
+ (str (.getCanonicalPath base) "/?") ""))
+
+(defn find-files [src-dirs test-dirs]
+ (let [src-files (mapcat #(filter (fn [f]
+ (and (memfn isFile)
+ (re-find #"\.clj$" (.getName f))))
+ (file-seq (.getCanonicalFile (file %))))
+ src-dirs)
+ test-files (mapcat #(filter (fn [f]
+ (and (memfn isFile)
+ (re-find #"\.clj$" (.getName f))))
+ (file-seq (.getCanonicalFile (file %))))
+ test-dirs)
+ dirs (concat src-dirs test-dirs)
+ base (if (= 1 (count dirs))
+ (file (first dirs))
+ (common-ancestor (map file dirs)))]
+ [base src-files test-files]))
View
29 src/procrustes/line_count.clj
@@ -0,0 +1,29 @@
+(ns procrustes.line-count
+ (:use [clojure.java.io :only [reader file]]
+ [procrustes.file :only [common-ancestor canonicalize-file find-files]])
+ (:import (java.io File)))
+
+(defn code? [line]
+ (let [line (.trim line)]
+ (and (not= (.length line) 0)
+ (not= (.charAt line 0) \;))))
+
+(defn line-count [base file]
+ {(canonicalize-file file base)
+ (count (filter code?
+ (line-seq (reader file))))})
+
+(defn line-counts
+ ([src-dirs test-dirs]
+ (apply line-counts (find-files src-dirs test-dirs)))
+ ([base src-files test-files]
+ (let [src-stats (reduce merge {} (map (partial line-count base)
+ src-files))
+ stats (if (empty? src-stats)
+ {}
+ {:file {:src src-stats}})
+ test-stats (reduce merge {} (map (partial line-count base)
+ test-files))]
+ (if (empty? test-stats)
+ stats
+ (update-in stats [:file] assoc :test test-stats)))))
View
73 src/procrustes/unused_deps.clj
@@ -1,73 +0,0 @@
-(ns procrustes.unused-deps
- (:use [procrustes.code :only [search-code find-ns-form but-ns-form
- find-ns-name read-code]]))
-
-(defn- use? [code]
- (and (list? code) (= :use (first code))))
-
-(defn- find-uses [code]
- (mapcat rest (search-code (find-ns-form code) use?)))
-
-(defn- find-use-onlys [code]
- (reduce merge {}
- (map (fn [[ k _ v]] (hash-map k v))
- (filter #(= :only (second %)) (find-uses code)))))
-
-(defn- used? [code sym]
- (not (empty? (search-code code (partial = sym)))))
-
-(defn- remove-used-use-only-syms [code uses]
- (reduce (fn [m [ns syms]]
- (merge m {ns (remove (partial used? code) syms)}))
- {}
- uses))
-
-(defn- unused-uses [code]
- (let [but-ns-form (but-ns-form code)]
- (->> code
- (find-use-onlys)
- (remove-used-use-only-syms but-ns-form)
- (remove (fn [[ns syms]]
- (empty? syms)))
- (mapcat (fn [[ns syms]]
- (map (fn [sym]
- (symbol (str ns "/" sym)))
- syms))))))
-
-(defn- require? [code]
- (and (list? code) (= :require (first code))))
-
-(defn- find-requires [code]
- (mapcat rest (search-code (find-ns-form code) require?)))
-
-(defn- find-require-ases [code]
- (reduce merge {}
- (map (fn [[ k _ v]] (hash-map k v))
- (filter #(= :as (second %)) (find-requires code)))))
-
-(defn- require-as-used? [code name]
- (not (empty? (search-code code (fn [code]
- (and (symbol? code)
- (.startsWith (str code)
- (str name "/"))))))))
-
-(defn- remove-used-require-ases [code requires]
- (remove (fn [[ns name]]
- (require-as-used? code name))
- requires))
-
-(defn- unused-requires [code]
- (let [but-ns-form (but-ns-form code)]
- (->> code
- (find-require-ases)
- (remove-used-require-ases but-ns-form)
- (map first))))
-
-(defn unused-deps [files]
- (->> files
- (map read-code)
- (map (fn [code]
- {(find-ns-name code)
- (concat (unused-uses code)
- (unused-requires code))}))
- (reduce merge {})))
View
64 src/procrustes/unused_names.clj
@@ -0,0 +1,64 @@
+(ns procrustes.unused-names
+ (:use [procrustes.code :only [search-code ns? ns-requires ns-uses
+ read-code-from-file blocks]]
+ [procrustes.file :only [find-files canonicalize-file]]
+ [clojure.java.io :only [file]]
+ [clojure.set :only [union]]))
+
+(defn namespace? [name e]
+ (and (or (symbol? e)
+ (keyword? e))
+ (= (namespace e) (str name))))
+
+(defn unused-required-names [ns requires body]
+ (->> requires
+ (filter (fn [r]
+ (let [[name r] (first r)]
+ (empty? (search-code (partial namespace? name)
+ body)))))
+ (map (fn [r]
+ (let [[name r] (first r)]
+ name)))
+ set))
+
+(defn unused-used-names [ns uses body]
+ (apply concat
+ (for [use uses]
+ (let [[ns names] (first use)]
+ (->> names
+ (filter (fn [n]
+ (empty? (search-code (partial = n) body))))
+ (map (fn [n] (symbol (str ns) (str n))))
+ set)))))
+
+(defn unused-names-in-ns [[ns & body]]
+ (let [body (if (not (ns? ns))
+ (cons ns body)
+ body)
+ unused-required-names (unused-required-names (second ns)
+ (ns-requires ns)
+ body)
+ unused-used-names (unused-used-names (second ns)
+ (ns-uses ns)
+ body)]
+ (union unused-required-names unused-used-names)))
+
+(defn unused-names-in-file [base file]
+ (let [unused-names (reduce union (map unused-names-in-ns
+ (blocks (read-code-from-file file))))]
+ (if (empty? unused-names)
+ {}
+ {:file {(canonicalize-file file base)
+ unused-names}})))
+
+(defn unused-names
+ ([src-dirs test-dirs]
+ (apply unused-names (find-files src-dirs test-dirs)))
+ ([base src-files test-files]
+ (let [src-names (->> src-files
+ (map (partial unused-names-in-file base))
+ (reduce (partial merge-with merge) {}))
+ test-names (->> test-files
+ (map (partial unused-names-in-file base))
+ (reduce (partial merge-with merge) {}))]
+ (merge-with merge src-names test-names))))
View
109 test/procrustes/test/code.clj
@@ -1,7 +1,8 @@
(ns procrustes.test.code
+ (:refer-clojure :exclude [ns-name])
(:use [procrustes.code] :reload)
(:use [clojure.test])
- (:use [clojure.java.io :only [input-stream]]))
+ (:use [clojure.java.io :only [input-stream reader]]))
(deftest test-read-code
(is (= '[(ns procrustes.example
@@ -19,36 +20,94 @@
(def- bar (delay (println \"Hello, World!\")))")))))
-(deftest test-find-ns-form
- (is (= '(ns procrustes.example
- (:use [clojure.contrib.io :only [to-byte-array]]))
- (find-ns-form (read-code (.getBytes "(ns procrustes.example
- (:use [clojure.contrib.io :only [to-byte-array]]))
+(deftest test-ns-require-name
+ (is (= 'bar (ns-require-name '[bar])))
+ (is (= 'bar (ns-require-name '(bar))))
+ (is (= 'quux (ns-require-name '[bar :as quux]))))
- (defn foo [x]
- (to-byte-array))
+(deftest test-ns-requires
+ (is (= '#{{clojure.contrib.graph clojure.contrib.graph}
+ {mk clojure.contrib.mock}
+ {clojure.contrib.import-static clojure.contrib.import-static}}
+ (set (ns-requires '(ns procrustes.example
+ (:require [clojure.contrib.graph]
+ clojure.contrib.import-static)
+ (:use [clojure.contrib.io :only [to-byte-array]])
+ (:require [clojure.contrib.mock :as mk]))))))
+ (testing "preserves metadata"
+ (let [requires (ns-requires
+ (first (read-code (.getBytes "(ns foo.bar
+ (:require [clojure.contrib.graph]
+ clojure.contrib.import-static)
+ (:require [clojure.contrib.mock :as mk])) "))))]
+ (is (= {:line 2}
+ (meta (nth requires 0))))
+ (is (= {:line 2}
+ (meta (nth requires 1))))
+ (is (= {:line 4}
+ (meta (nth requires 2)))))))
- (def- bar (delay (println \"Hello, World!\")))"))))))
+(deftest test-ns-uses
+ (is (= '#{{clojure.contrib.io [to-byte-array copy]}
+ {clojure.contrib.condition [raise]}}
+ (set (ns-uses '(ns procrustes.example
+ (:require [clojure.contrib.graph])
+ (:use [clojure.contrib.io :only [to-byte-array
+ copy]])
+ (:use [clojure.contrib.import-static])
+ (:use [clojure.contrib.condition :only [raise]])
+ (:require [clojure.contrib.mock :as mk]))))))
+ (testing "preserves metadata"
+ (let [uses (ns-uses
+ (first (read-code (.getBytes "(ns foo.bar
+ (:use [clojure.contrib.io :only [file]])
+ (:use [foo.bar :only [baz]]
+ [baz.foo :only [quux]]))"))))]
+ (is (= {:line 2}
+ (meta (nth uses 0))))
+ (is (= {:line 3}
+ (meta (nth uses 1))))
+ (is (= {:line 3}
+ (meta (nth uses 2)))))))
-(deftest test-find-ns-name
- (is (= 'procrustes.example
- (find-ns-name (read-code (.getBytes "(ns procrustes.example
- (:use [clojure.contrib.io :only [to-byte-array]]))
+(deftest test-blocks
+ (let [code (.getBytes "(defn foo [bar] (println bar))
- (defn foo [x]
- (to-byte-array))
+ (ns foo.bar
+ (:use [clojure.contrib :only [file]]))
- (def- bar (delay (println \"Hello, World!\")))"))))))
+ (defn baz [x]
+ x)
-(deftest test-but-ns-form
- (is (= '[(defn foo [x]
- (to-byte-array))
+ (ns baz)
+ (def PI 3.14)")]
+ (is (= '[[(ns user)
+ (defn foo [bar] (println bar))]
+ [(ns foo.bar
+ (:use [clojure.contrib :only [file]]))
- (def- bar (delay (println "Hello, World!")))]
- (but-ns-form (read-code (.getBytes "(ns procrustes.example
- (:use [clojure.contrib.io :only [to-byte-array]]))
+ (defn baz [x]
+ x)]
+ [(ns baz)
+ (def PI 3.14)]]
+ (blocks (read-code code))))))
- (defn foo [x]
- (to-byte-array))
+(deftest test-search-code
+ (let [code (.getBytes "(defn foo [bar] (println bar))
+
+ (ns foo.bar
+ (:use [clojure.contrib :only [file]]
+ [bar.baz]))
+
+ (defn baz [x]
+ x)
- (def- bar (delay (println \"Hello, World!\")))"))))))
+ (ns baz)
+ (def PI 3.14)")
+ use-form (first (search-code (partial application? :use)
+ (read-code code)))]
+ (is (= {:line 4}
+ (meta (first (search-code (fn [e]
+ (and (vector? e)
+ (= (first e) 'bar.baz)))
+ use-form)))))))
View
18 test/procrustes/test/line_count.clj
@@ -0,0 +1,18 @@
+(ns procrustes.test.line-count
+ (:use [procrustes.line-count] :reload)
+ (:use [clojure.test]))
+
+(deftest test-line-counts
+ (is (= {:file {:src {"src/line_count/core.clj" 1},
+ :test {"test/line_count/test/core.clj" 5}}}
+ (line-counts ["fixtures/line-count/src/"]
+ ["fixtures/line-count/test"])))
+ (is (= {:file {:src {"line_count/core.clj" 1}}}
+ (line-counts ["fixtures/line-count/src/"]
+ [])))
+ (is (= {:file {:test {"line_count/test/core.clj" 5}}}
+ (line-counts []
+ ["fixtures/line-count/test"])))
+ (is (= {}
+ (line-counts []
+ []))))
View
20 test/procrustes/test/unused_deps.clj
@@ -1,20 +0,0 @@
-(ns procrustes.test.unused-deps
- (:use [procrustes.unused-deps] :reload)
- (:use [clojure.test]
- [procrustes.code :only [read-code]]))
-
-(deftest test-unused-deps
- (is (= '{procrustes.example [clojure.java.io/file
- clojure.contrib.monads]}
- (unused-deps [(.getBytes "(ns procrustes.example
- (:require [clojure.contrib.monads :as monad]
- [clojure.contrib.ns-utils :as utils])
- (:use [clojure.contrib.io :only [to-byte-array]]
- [clojure.java.io :only [file]])
- (:use [clojure.contrib.mock]))
-
- (defn foo [x]
- (utils/docs procrustes.example)
- (to-byte-array))
-
- (def- bar (delay (println \"Hello, World!\")))")]))))
View
11 test/procrustes/test/unused_names.clj
@@ -0,0 +1,11 @@
+(ns procrustes.test.unused-names
+ (:use [procrustes.unused-names] :reload)
+ (:use [clojure.test]
+ [procrustes.code :only [read-code]]))
+
+(deftest test-unused-names
+ (is (= '{:file {"src/unused_names/core.clj"
+ #{clojure.contrib.combinatorics cl
+ clojure.contrib.graph/add-loops}}}
+ (unused-names ["fixtures/unused-names/src"]
+ ["fixtures/unused-names/test"]))))
Please sign in to comment.
Something went wrong with that request. Please try again.