Skip to content

Commit

Permalink
New tests and updated docs around validation pipelining
Browse files Browse the repository at this point in the history
  • Loading branch information
theleoborges committed Mar 15, 2013
1 parent 07418a7 commit 97b036e
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -8,3 +8,4 @@ pom.xml
.lein-deps-sum
.lein-failures
.lein-plugins
.lein-repl-history
1 change: 1 addition & 0 deletions 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)

Expand Down
18 changes: 17 additions & 1 deletion README.md
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion project.clj
Expand Up @@ -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"]})
12 changes: 12 additions & 0 deletions test/bouncer/core_test.clj
Expand Up @@ -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.