Skip to content

Commit

Permalink
Updated to 0.9.7.
Browse files Browse the repository at this point in the history
  • Loading branch information
bow-fujita committed May 5, 2016
1 parent 4da2dd4 commit b101f4b
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 17 deletions.
78 changes: 77 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ app.delete('/api/example/:id', example.remove);
+ **`authorizer`: Function [Default: `undefined`]**<br>
Middleware for user authorization.

+ **`templates`: Object [Default: `{ crud: [...] }`]**<br>
Templates for routes.

Each controller module implemented in `opts.controllers` directory will be mapped onto `opts.url`.
You don't have to code for routing by yourself.
Expand Down Expand Up @@ -214,6 +216,9 @@ The following properties will be applied to each element in `routes`:
+ **`middleware`: {Function|Function[]} [Default: `undefined`]**<br>
[Middleware(s)](#middleware) to be passed to Express.

+ **`template`: String [Default: `undefined`]**<br>
One of [templates](#template) to be used as `routes`.


### Validator

Expand Down Expand Up @@ -300,7 +305,6 @@ module.exports = {
};
```
### Middleware
`middleware` is typically used for APIs accept file uploading.
Expand Down Expand Up @@ -379,6 +383,78 @@ module.exports = {
};
```
### Template
`template` is an option to avoid defining the same `routes` in multiple controllers.
Once you define routes which might be used often in several controllers, then feed them to `route()` with `opts.templates`, each controller can refer one of the templates through `preset.template` property.
The following example shows how to use template:
```javascript
// app.js

var express = require('express')
, exprest = require('exprest4')
, app = express()
, templates = {
queue: [{
action: 'push'
, path: ':elem'
, method: 'post'
}, {
action: 'pop'
, method: 'delete'
}]
}
;

exprest.route(app, { templates: templates })
```
```javascript
// controllers/seat.js
var waiting_list = [];

module.exports = {
__exprest: {
preset: {
template: 'queue'
}
// No routes required here.
}

, push: function(req, res) {
waiting_list.push(req.params.elem);
res.status(200).json(waiting_list);
}
, pop: function(req, res) {
waiting_list.pop();
res.status(200).json(waiting_list);
}
};
```
`exprest4` provides the following template `crud` by default which might be useful for CRUD-based REST APIs:
```javascript
[{
action: 'list'
}, {
action: 'view'
, path: ':id'
}, {
action: 'create'
, method: 'post'
}, {
action: 'update'
, path: ':id'
, method: 'put'
}, {
action: 'remove'
, path: ':id'
, method: 'delete'
}]
```
## License
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "exprest4",
"version": "0.9.6",
"version": "0.9.7",
"description": "REST API framework for Express 4.x.",
"homepage": "https://github.com/bow-fujita/exprest4",
"repository": {
Expand Down
15 changes: 15 additions & 0 deletions test/controllers/errors/invalid_template/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*!
* exprest4
* Copyright (c) 2016 Hiromitsu Fujita <bow.fujita@gmail.com>
* MIT License
*/

'use strict';

module.exports = {
__exprest: {
preset: {
template: 'invalid'
}
}
};
15 changes: 15 additions & 0 deletions test/controllers/errors/unknown_template/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*!
* exprest4
* Copyright (c) 2016 Hiromitsu Fujita <bow.fujita@gmail.com>
* MIT License
*/

'use strict';

module.exports = {
__exprest: {
preset: {
template: 'unknown'
}
}
};
5 changes: 1 addition & 4 deletions test/controllers/templates/queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ module.exports = {
, dump: function(req, res) {
res.status(200).json({ action: 'dump', queue: queue });
}

, push: function(req, res) {
queue.push(req.params.elem);
res.status(200).json({ action: 'push', queue: queue });
}

, pop: function(req, res) {
queue.pop();
res.status(200).json({ action: 'pop', queue: queue });
}

}
};
47 changes: 40 additions & 7 deletions test/suites/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,76 @@ describe('config error', function() {
});

it('no __exprest', function(done) {
exprest.route(app, { controllers: path.join(ctrl_dir, 'no_exprest') })
exprest.route(app, {
controllers: path.join(ctrl_dir, 'no_exprest')
})
.should.be.rejectedWith(/No __exprest defined/)
.then(function() { done(); }, done);
});

it('invalid __exprest', function(done) {
exprest.route(app, { controllers: path.join(ctrl_dir, 'invalid_exprest') })
exprest.route(app, {
controllers: path.join(ctrl_dir, 'invalid_exprest')
})
.should.be.rejectedWith(/Invalid __exprest/)
.then(function() { done(); }, done);
});

it('unknown_template', function(done) {
exprest.route(app, {
controllers: path.join(ctrl_dir, 'unknown_template')
})
.should.be.rejectedWith(/Unknown template/)
.then(function() { done(); }, done);
});

it('invalid_template', function(done) {
exprest.route(app, {
controllers: path.join(ctrl_dir, 'invalid_template')
, templates: {
invalid: {}
}
})
.should.be.rejectedWith(/Invalid template/)
.then(function() { done(); }, done);
});

it('no routes', function(done) {
exprest.route(app, { controllers: path.join(ctrl_dir, 'no_routes') })
exprest.route(app, {
controllers: path.join(ctrl_dir, 'no_routes')
})
.should.be.rejectedWith(/No __exprest\.routes defined/)
.then(function() { done(); }, done);
});

it('invalid routes', function(done) {
exprest.route(app, { controllers: path.join(ctrl_dir, 'invalid_routes') })
exprest.route(app, {
controllers: path.join(ctrl_dir, 'invalid_routes')
})
.should.be.rejectedWith(/Invalid __exprest\.routes/)
.then(function() { done(); }, done);
});

it('unknown method', function(done) {
exprest.route(app, { controllers: path.join(ctrl_dir, 'unknown_method') })
exprest.route(app, {
controllers: path.join(ctrl_dir, 'unknown_method')
})
.should.be.rejectedWith(/Unknown method \"test\" in __exprest\.routes\[0\]\.method/)
.then(function() { done(); }, done);
});

it('no action defined', function(done) {
exprest.route(app, { controllers: path.join(ctrl_dir, 'no_action_def') })
exprest.route(app, {
controllers: path.join(ctrl_dir, 'no_action_def')
})
.should.be.rejectedWith(/No __exprest\.routes\[0\]\.action defined/)
.then(function() { done(); }, done);
});

it('no action implemented', function(done) {
exprest.route(app, { controllers: path.join(ctrl_dir, 'no_action_imp') })
exprest.route(app, {
controllers: path.join(ctrl_dir, 'no_action_imp')
})
.should.be.rejectedWith(/No view\(\) implemented/)
.then(function() { done(); }, done);
});
Expand Down
12 changes: 8 additions & 4 deletions test/suites/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('options', function() {
, '[exprest4] app.post("/user") loaded.'
, '[exprest4] app.put("/user/:id") loaded.'
, '[exprest4] app.delete("/user/:id") loaded.'
, '[exprest4] Invoking list() upon app.get("/user").'
]
, actual_logs = []
;
Expand All @@ -36,10 +37,13 @@ describe('options', function() {
})
.should.be.fulfilled()
.then(function() {
expected_logs.forEach(function(expected) {
expected.should.be.equalOneOf(actual_logs);
});
done();
request(app).get('/user')
.expect(200, function() {
expected_logs.forEach(function(expected) {
expected.should.be.equalOneOf(actual_logs);
});
done();
});
});

}); // logger
Expand Down

0 comments on commit b101f4b

Please sign in to comment.