Commits

Miki Tebeka  committed b00f258

Conversions and adding missing tests

  • Participants
  • Parent commits 34824e9

Comments (0)

Files changed (2)

File src/csvlib.clj

 (ns csvlib
   (import com.csvreader.CsvReader))
 
-(defn- record-seq [filename]
+(defn make-converter
+  "Make a converter function from a conversion table"
+  [converison]
+  (let [convert (fn [key value] ((get converison key identity) value))]
+    (fn [record]
+      (zipmap (keys record) (map #(convert % (record %)) (keys record))))))
+
+(defn- record-seq 
+  "Reutrn a lazy sequence of records from a CSV file"
+  [filename]
   (let [csv (CsvReader. filename)
         read-record (fn [] 
                       (when (.readRecord csv) 
 (defn read-csv
   "Return a lazy sequence of records (maps) from CSV file.
 
-  With header map will be header->value, otherwise it'll be position->value."
-  ([filename] (read-csv filename false))
-  ([filename headers?]
+  With header map will be header->value, otherwise it'll be position->value.
+  `conversions` is an optional map from header to a function that convert the
+  value."
+  ([filename] (read-csv filename false nil))
+  ([filename headers?] (read-csv filename headers? nil))
+  ([filename headers? conversion]
    (let [records (record-seq filename)
+         convert (make-converter conversion)
          headers (if headers? (first records) (range (count (first records))))]
-    (map #(zipmap headers %) (if headers? (rest records) records)))))
+     (map convert
+          (map #(zipmap headers %) (if headers? (rest records) records))))))
   

File test/csvlib_test.clj

+(ns csvlib-test
+  (:use [csvlib] :reload-all)
+  (:use [clojure.test]))
+
+(deftest test-no-headers
+  (let [records (read-csv "test/toons.csv")]
+    (is (= (count records) 4))
+    (is (= (first records) {0 "Name" 1 "Animal" 2 "Funny"}))
+    (is (= (last records) { 0 "Elmer" 1 "Pig" 2 "No"}))))
+
+(deftest test-headers
+  (let [records (read-csv "test/toons.csv" true)]
+    (is (= (count records) 3))
+    (is (= (first records) {"Name" "Duffy" "Animal" "Duck" "Funny" "Yes"}))
+    (is (= (last records) { "Name" "Elmer" "Animal" "Pig" "Funny" "No"}))))
+
+(deftest test-convert
+  (let [conversion {"Funny" {"Yes" true "No" false}}
+        records (read-csv "test/toons.csv" true conversion)]
+    (is (= (count records) 3))
+    (is (= ((first records) "Funny") true))))