diff options
-rw-r--r-- | src/clojure/contrib/java_utils.clj | 60 | ||||
-rw-r--r-- | src/clojure/contrib/test_contrib.clj | 4 | ||||
-rw-r--r-- | src/clojure/contrib/test_contrib/test_java_utils.clj | 37 |
3 files changed, 100 insertions, 1 deletions
diff --git a/src/clojure/contrib/java_utils.clj b/src/clojure/contrib/java_utils.clj new file mode 100644 index 00000000..1ea420ea --- /dev/null +++ b/src/clojure/contrib/java_utils.clj @@ -0,0 +1,60 @@ +; Copyright (c) Stuart Halloway, April 2009. All rights reserved. +; The use and distribution terms for this software are covered by the +; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +; which can be found in the file epl-v10.html at the root of this distribution. +; By using this software in any fashion, you are agreeing to be bound by +; the terms of this license. +; You must not remove this notice, or any other, from this software. + +; Design goals: +; +; (1) Ease-of-use. These APIs should be convenient. Performance is secondary. +; +; (2) Duck typing. I hate having to think about the difference between +; a string that names a file, and a File. Ditto for a ton of other +; wrapper classes in the Java world (URL, InternetAddress). With these +; APIs you should be able to think about domain equivalence, not type +; equivalence. +; +; (3) No bossiness. I am not marking any of these functions as private; +; the docstrings will tell you the intended usage but do what works for you. +; +; Feedback welcome! +; +; If something in this module violates the principle of least surprise, please +; let me (Stu) and the Clojure community know via the mailing list. + +(ns clojure.contrib.java-utils + (:import [java.io File])) + +(defmulti relative-path-string + "Interpret a String or java.io.File as a relative path string. + Building block for clojure.contrib.java-utils/file." + class) + +(defmethod relative-path-string String [s] + (relative-path-string (File. s))) + +(defmethod relative-path-string File [f] + (if (.isAbsolute f) + (throw (IllegalArgumentException. (str f " is not a relative path"))) + (.getPath f))) + +(defmulti as-file + "Interpret a String or a java.io.File as a File. Building block + for clojure.contrib.java-utils/file, which you should prefer + in most cases." + class) +(defmethod as-file String [s] (File. s)) +(defmethod as-file File [f] f) + +(defn file + "Returns a java.io.File from string or file args." + ([arg] + (as-file arg)) + ([parent child] + (File. (as-file parent) (relative-path-string child))) + ([parent child & more] + (reduce file (file parent child) more))) + +
\ No newline at end of file diff --git a/src/clojure/contrib/test_contrib.clj b/src/clojure/contrib/test_contrib.clj index 8e35e4b9..88e2b42e 100644 --- a/src/clojure/contrib/test_contrib.clj +++ b/src/clojure/contrib/test_contrib.clj @@ -16,7 +16,7 @@ (:use [clojure.contrib.test-is :only (run-tests)]) (:gen-class)) -(def test-names [:complex-numbers :monads :str-utils :shell-out :test-graph :test-dataflow]) +(def test-names [:complex-numbers :monads :str-utils :shell-out :test-graph :test-dataflow :test-java-utils]) (def test-namespaces (map #(symbol (str "clojure.contrib.test-contrib." (name %))) @@ -34,3 +34,5 @@ [& args] (run) (System/exit 0)) + +(run)
\ No newline at end of file diff --git a/src/clojure/contrib/test_contrib/test_java_utils.clj b/src/clojure/contrib/test_contrib/test_java_utils.clj new file mode 100644 index 00000000..9c536322 --- /dev/null +++ b/src/clojure/contrib/test_contrib/test_java_utils.clj @@ -0,0 +1,37 @@ +(ns clojure.contrib.test-contrib.test-java-utils + (:use clojure.contrib.test-is + clojure.contrib.java-utils) + (:import [java.io File])) + +(deftest test-relative-path-string + (testing "strings" + (is (= "foo" (relative-path-string "foo")))) + (testing "absolute path strings are forbidden" + (is (thrown? IllegalArgumentException (relative-path-string "/baz")))) + (testing "relative File paths" + (is (= "bar" (relative-path-string (File. "bar"))))) + (testing "absolute File paths are forbidden" + (is (thrown? IllegalArgumentException (relative-path-string (File. "/quux"))))) +) + +(deftest test-as-file + (testing "strings" + (is (= (File. "foo") (as-file "foo")))) + (testing "Files" + (is (= (File. "bar") (as-file (File. "bar"))))) +) + +(deftest test-file + (testing "single argument" + (is (= (File. "foo") (file "foo")))) + (testing "two arguments" + (is (= (File. "foo/bar") (file "foo" "bar")))) + (testing "N arguments" + (is (= (File. "foo/bar/baz/quux") (file "foo" "bar" "baz" "quux")))) + (testing "no sneaking in absolute paths!" + (is (thrown? IllegalArgumentException (file "foo" "bar" "/boom" "baz" "quux")))) +) + + + + |