Skip to content

Instantly share code, notes, and snippets.

@jcromartie
Created July 29, 2011 03:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcromartie/1113067 to your computer and use it in GitHub Desktop.
Save jcromartie/1113067 to your computer and use it in GitHub Desktop.
(ns cklist.validation
(:use clojure.test))
(defn- vresult
[k msg]
{k #{msg}})
(defn required
"Returns validator which requires field to be non-empty"
[msg k]
(fn [m]
(let [x (get m k)]
(when (or (nil? x)
(empty? (.trim (str x))))
(vresult k msg)))))
(defn regex
"Returns validator which requires field in k to match regular expression re"
[msg k re]
(fn [m]
(when-not (re-find re (str (get m k)))
(vresult k msg))))
(defn must-match
"Returns validator which requires value of inputs to match"
[msg & ks]
(fn [m]
(when-not (apply = (map #(get m %) ks))
(apply merge (map #(vresult % msg) ks)))))
(defn validator
"Used to make compound validators.
Returns fn which takes a map m of form input parameters and runs it
through the supplied validator fns, gathering the validation results
into a map of keys to messages"
[& fns]
(fn [m]
(apply merge-with into
(map #(% m) fns))))
(deftest test-validators
(let [re (regex "nope" :x #".{6,}")
rq (required "nope" :x)
m (must-match "nope" :x :y)
err1 {:x #{"nope"}}]
(is (= nil (re {:x "looooong"})))
(is (= err1 (re {:x "short"})))
(is (= nil (rq {:x 1})))
(is (= err1 (rq {:x nil})))
(is (= err1 (rq {:x ""})))
(is (= {:x #{"nope"} :y #{"nope"}} (m {:x 1 :y 2})))
(is (= nil (m {:x 1 :y 1})))))
(deftest test-compound-validator
(is (= {:x #{"too short"} :foo #{"missing"}}
((validator
(regex "too short" :x #".{6,}")
(must-match "nope" :y :z)
(required "missing" :foo))
{:x "short" :y 1 :z 1}))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment