Skip to content

Commit

Permalink
added validation library
Browse files Browse the repository at this point in the history
  • Loading branch information
Enome committed Mar 18, 2012
1 parent ceb7bef commit a5df47f
Show file tree
Hide file tree
Showing 10 changed files with 622 additions and 0 deletions.
2 changes: 2 additions & 0 deletions validation/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
unittests:
@NODE_ENV=test mocha $(shell find specs -name "*.coffee") -r should
102 changes: 102 additions & 0 deletions validation/README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Square Validation

## Validators

The api for a validator looks like:

``` coffee-script
required: (msg)->

(data, invalid, valid)->

try
check(data, msg).notEmpty()
catch e
return invalid e.message

valid data
```

Function that returns a function that takes the data to validate and two callbacks. If the data is invalid call invalid with the error message. If the data is valid call valid with the (sanitized) data.

## Create

``` coffee-script
{ required, string, integer, email } = require( 'square-validator' ).validators
{ create } = require 'square-validator'

# Validation Map

user = create
name: [ required(), string() ]
age: [ integer() ]
email: [ required(), email() ]
password: [ required() ]

# Remove fields you don't need

sanitize = password: false

# Create user

User = create user, sanitize

# Instantiate user with data

geert = User name: 'Geert', age: 29, email: 'geert.pasteels@gmail.com', password: '1234'

# If valid it will call valid if not it will call invalid

geert.validate

valid: (data)->
# data is sanitized data

invalid: (errors)->
# Errors is an object with keys and an array of error(s)
```

## Middleware

Middleware to use with express. The middleware expects the validator at locals().validator.

``` coffee-script
{ create, middleware, validators } = require( 'square-validator' )
{ required, string, integer, email } = validators

# Define your validator in a middleware

createValidator = (req, res, next)->

user = create
name: [ required(), string() ]
age: [ integer() ]
email: [ required(), email() ]
password: [ required() ]

# Remove fields you don't need

sanitize = password: false

# Create user

User = create user, sanitize

res.local 'validator', ( User req.body )

next()

# Your route might look like the following:

app.get '/', createValidator, middleware('error_view'), ...

```
If the data is invalid it will render error_view with the local errors and return the req.body as the local form_model. If the data is valid next will be called and the local validated_data will be set with your sanitized data.

## Run tests

Tests use mocha and should.

``` shell
make unittests
```
4 changes: 4 additions & 0 deletions validation/index.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports =
create: require './src/validate'
validators: require './src/validators'
middleware: require './src/middleware'
16 changes: 16 additions & 0 deletions validation/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "square-validation",
"version" : "0.0.1",
"repository": { "type": "git", "url": "git://github.com/Enome/square" },
"description": "Validates and sanitizes objects. Has middleware for with express.js",
"main": "index",
"author": "Geert Pasteels <twitter.com/enome>",
"keywords": [ "validation", "express" ],
"dependencies": {
"validator": "*"
},
"devDependencies": {
"should": "*",
"express-recorder": "*"
}
}
82 changes: 82 additions & 0 deletions validation/specs/middleware.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
recorder = ( require 'express-recorder' ).middleware

{ required, compare } = require '../src/validators'
create = require '../src/validate'

middleware = require '../src/middleware'

extend = (o1, o2)->
n = {}
n[k] = v for k, v of o1
n[k] = v for k,v of o2
n

credentials = create

name: [ required() ]
username: [ required() ]
password: [ compare() ]
password1: [ required() ]
password2: [ required() ]
,
password1: false
password2: false

createLocalValidator = (data)->

credentials data

describe 'middleware', ->

badCredentials =
name: 'Geert'
username: ''
password: ['1234', '5678']
password1: '1234'
password2: '5678'

body = somestuff: 'doesnt matter'

goodCredentials =
name: 'Geert'
username: 'Pickels'
password: ['1234', '1234']
password1: '1234'
password2: '1234'

describe ':(', ->

it 'renders the form view and sets the errors and form_model locals', (done)->

locals = validator: createLocalValidator(badCredentials)

recorder middleware.validate('form') , { body, locals }, (result)->

result.eql
locals:
form_model: somestuff: 'doesnt matter'
validator: locals.validator
errors:
username: [ 'String is empty' ]
password: [ 'Values are not equal' ]

render: 'form'

done()

describe ':)', ->

it 'renders the form view and sets the errors and form_model locals', (done)->

locals = validator: createLocalValidator(goodCredentials)

recorder middleware.validate('form') , { body, locals }, (result)->

result.eql
locals:
validator: locals.validator
validated_data: name: 'Geert', username: 'Pickels', password: '1234'

next: [true]

done()
116 changes: 116 additions & 0 deletions validation/specs/validate.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
create = require '../src/validate'
{ required, string, integer, email } = require '../src/validators'

describe 'Example one', ->

user =
name: [ required() ]

validUser = User = null

beforeEach ->

User = create user


describe ':( path', ->

geert = null

beforeEach ->

geert = User name: ''


it 'calls invalid', (done)->

geert.validate

invalid: (errors)->

errors.should.eql

name: [ 'String is empty' ]

done()


describe ':) path', ->

geert = null

beforeEach ->

geert = User name: 'Geert'


it 'calls valid', (done)->

geert.validate

valid: (data)->

data.should.eql name: 'Geert'

done()


describe 'Example 2', ->

user =
name: [ required(), string() ]
age: [ integer() ]
email: [ required(), email() ]
password: [ required() ]

sanitize =
password: false

geert = User = null

beforeEach ->

User = create user, sanitize


describe ':( path', ->

beforeEach ->

geert = User name: '', age: 'i15.00', email: ''


it 'returns all the errors', (done)->

geert.validate

invalid: (errors)->

errors.should.eql
name: [ 'String is empty' ]
age: [ 'Invalid integer' ]
email: [ 'String is empty', 'Invalid email' ]
password: [ 'String is empty' ]

done()


describe ':) path', ->

beforeEach ->

geert = User name: 'Geert', age: '15', email: 'geert.pasteels@gmail.com', password: '1234'


it 'returns the sanitized object', (done)->

geert.validate

valid: (data)->

data.should.eql
name: 'Geert'
age: 15
email: 'geert.pasteels@gmail.com'

done()
Loading

0 comments on commit a5df47f

Please sign in to comment.