diff --git a/.gitignore b/.gitignore index ee508f7..0f99dc5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ pom.xml .lein-deps-sum .lein-failures .lein-plugins +.lein-repl-history \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index dd7ff3a..25a75de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.2.3 (UNRELEASED) - Validator sets can now be used at the top level call to `validate` and `valid?`. +- Added tested and a doc section around validation pipelining. It was an undocumented invariant. See discussion [here](https://github.com/leonardoborges/bouncer/pull/4). ## 0.2.2 (16/01/2013) diff --git a/README.md b/README.md index 4c0f305..3919231 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A validation DSL for Clojure apps ## Table of Contents -* [API Docs](http://leonardoborges.github.com/bouncer/) +* [Annotated Source](http://leonardoborges.github.com/bouncer/) * [Motivation](#motivation) * [Setup](#setup) * [Usage](#usage) @@ -12,6 +12,7 @@ A validation DSL for Clojure apps * [Validating nested maps](#validating-nested-maps) * [Multiple validation errors](#multiple-validation-errors) * [Validating collections](#validating-collections) + * [Validation pipelining](#validation-pipelining) * [Composability: validator sets](#composability-validator-sets) * [Customization support](#customization-support) * [Custom validators using arbitrary functions](#custom-validations-using-arbitrary-functions) @@ -184,6 +185,21 @@ Let's see it in action: All we need to do is provide a predicate function to `every`. It will be invoked for every item in the collection, making sure they all pass. +### Validation pipelining + +Note that if a map if pipelined through multiple validators, bouncer will leave it's errors map untouched and simply add new validation errors to it: + +```clojure +(-> {:age "NaN"} + (core/validate :name v/required) + second + (core/validate :age v/number) + second + ::core/errors) + +;; {:age ("age must be a number"), :name ("name must be present")} +``` + ## Composability: validator sets If you find yourself repeating a set of validators over and over, chances are you will want to group and compose them somehow. The macro `bouncer.validators/defvalidatorset` does just that: diff --git a/project.clj b/project.clj index c66b581..f6fdd74 100644 --- a/project.clj +++ b/project.clj @@ -8,4 +8,5 @@ :plugins [[lein-marginalia "0.7.1"]] :profiles {:1.3 {:dependencies [[org.clojure/clojure "1.3.0"]]} :1.4 {:dependencies [[org.clojure/clojure "1.4.0"]]} - :1.5 {:dependencies [[org.clojure/clojure "1.5.0-RC1"]]}}) + :1.5 {:dependencies [[org.clojure/clojure "1.5.0"]]}} + :aliases {"all-tests" ["with-profile" "1.3:1.4:1.5" "test"]}) diff --git a/test/bouncer/core_test.clj b/test/bouncer/core_test.clj index a4af071..675f20d 100644 --- a/test/bouncer/core_test.clj +++ b/test/bouncer/core_test.clj @@ -232,3 +232,15 @@ :dob v/number [:passport :number] v/positive [:address :past] (v/every #(not (nil? (:country %))))))))))) + + +(deftest pipelining-validations + (testing "should preserve the existing errors map if there is one" + (let [validation-errors (-> {:age "NaN"} + (core/validate :name v/required) + second + (core/validate :age v/number) + second + ::core/errors)] + (is (= 2 + (count (select-keys validation-errors [:age :name])))))))