Skip to content
Browse files

New tests and updated docs around validation pipelining

  • Loading branch information...
1 parent 07418a7 commit 97b036ec7062f7ecd570ffd06d6d93d9e537107b @leonardoborges committed Mar 15, 2013
Showing with 33 additions and 2 deletions.
  1. +1 −0 .gitignore
  2. +1 −0 CHANGELOG.md
  3. +17 −1 README.md
  4. +2 −1 project.clj
  5. +12 −0 test/bouncer/core_test.clj
View
1 .gitignore
@@ -8,3 +8,4 @@ pom.xml
.lein-deps-sum
.lein-failures
.lein-plugins
+.lein-repl-history
View
1 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)
View
18 README.md
@@ -4,14 +4,15 @@ 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)
* [Basic validations](#basic-validations)
* [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:
View
3 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"]})
View
12 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])))))))

0 comments on commit 97b036e

Please sign in to comment.
Something went wrong with that request. Please try again.