Skip to content

Commit

Permalink
remove content-type when 201 has no body. move test coverage to istan…
Browse files Browse the repository at this point in the history
…bul. version bump 0.3.0.
  • Loading branch information
cainus committed Apr 1, 2014
1 parent 95e22d4 commit baaf6ca
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 144 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,4 +1,5 @@
coverage.html
node_modules/
npm-debug.log
coverage

22 changes: 12 additions & 10 deletions Makefile
@@ -1,18 +1,20 @@
REPORTER = spec
test:
@NODE_ENV=test ./node_modules/.bin/mocha -b --reporter $(REPORTER) --recursive
@NODE_ENV=test ./node_modules/.bin/mocha -b --reporter $(REPORTER)

lib-cov:
./node_modules/jscoverage/bin/jscoverage lib lib-cov
lint:
./node_modules/.bin/jshint ./test ./index.js

test-cov: lib-cov
@JSON_STATUS_COVERAGE=1 $(MAKE) test REPORTER=html-cov 1> coverage.html
rm -rf lib-cov
test-cov:
$(MAKE) lint
@NODE_ENV=test ./node_modules/.bin/istanbul cover \
./node_modules/mocha/bin/_mocha -- -R spec

test-coveralls: lib-cov
$(MAKE) test REPORTER=spec
test-coveralls:
echo TRAVIS_JOB_ID $(TRAVIS_JOB_ID)
@JSON_STATUS_COVERAGE=1 $(MAKE) test REPORTER=mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js || true
rm -rf lib-cov
$(MAKE) test
@NODE_ENV=test ./node_modules/.bin/istanbul cover \
./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && \
cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js || true

.PHONY: test
130 changes: 126 additions & 4 deletions index.js
@@ -1,5 +1,127 @@
var dir = './lib/';
if (process.env.JSON_STATUS_COVERAGE){
dir = './lib-cov/';
var EventEmitter = require('events').EventEmitter;
var util = require('util');

var JsonResponder = function(req, res){
this.req = req;
this.res = res;
};

JsonResponder.connectMiddleware = function(namespace, errorHandler){
namespace = namespace || 'status';
return function(req, res, next){
res[namespace] = new JsonResponder(req, res);
if (errorHandler && (typeof errorHandler === 'function')){
res[namespace].on('error', errorHandler);
}
next();
};
};

JsonResponder.prototype = Object.create(EventEmitter.prototype);

var errors = {
'badRequest' : {type : 400, message : 'Bad Request'},
'unauthenticated' : {type : 401, message : 'Unauthenticated'},
'forbidden' : {type : 403, message : 'Forbidden'},
'notFound' : {type : 404, message : 'Not Found'},
'methodNotAllowed' : {type : 405, message : 'Method Not Allowed'},
'notAcceptable' : {type : 406, message : 'Not Acceptable'},
'conflict' : {type : 409, message : 'Conflict'},
'gone' : {type : 410, message : 'Gone'},
'lengthRequired' : {type : 411, message : 'Length Required'},
'preconditionFailed' : {type : 412, message : 'Precondition Failed'},
'requestEntityTooLarge' : {type : 413, message : 'Request Entity Too Large'},
'requestUriTooLong' : {type : 414, message : 'Request URI Too Long'},
'unsupportedMediaType' : {type : 415, message : 'Unsupported Media Type'},
'unprocessableEntity' : {type : 422, message : 'Unprocessable Entity'},
'tooManyRequests' : {type : 429, message : 'Too Many Requests'},
'internalServerError' : {type : 500, message : 'Internal Server Error'},
'notImplemented' : {type : 501, message : 'Not Implemented'},
'badGateway' : {type : 502, message : 'Bad Gateway'},
'serviceUnavailable' : {type : 503, message : 'Service Unavailable'},
'gatewayTimeout' : {type : 504, message : 'Gateway Timeout'}
};

var makeErrorHandler = function(name, payload){
JsonResponder.prototype[name] = function(detail){
var obj = {"error" : payload};

detail = detail || {};
// if detail is circular, just flatten it to a string.
try {
JSON.stringify(detail); // will throw if circular
} catch(ex) {
detail = util.inspect(detail); // stringifies. only goes one level deep.
}

obj.error.detail = detail;

this.res.setHeader('Content-Type', 'application/json; charset=utf-8');
this.res.writeHead(payload.type);
var out = JSON.stringify(obj);
this.res.write(out);
this.res.end();
this.emit("error", { req : this.req, res : this.res, type : payload.type, message : payload.message, detail : detail } );
};
};

/* set methods on the JsonResponder for every kind of error that could occur. */
for(var errorName in errors){
makeErrorHandler(errorName, errors[errorName]);
}
module.exports = require(dir + 'JsonResponder');

JsonResponder.prototype.created = function(url, data){
url = url || '';
this.res.setHeader('Location', url);
if (data){
this.res.setHeader('content-type', 'application/json');
}
this.res.writeHead(201);
if (data) {
this.res.end(JSON.stringify(data));
} else {
this.res.end();
}
};

JsonResponder.prototype.accepted = function(){
this.res.writeHead(202);
this.res.end();
};

JsonResponder.prototype.noContent = function(){
this.res.writeHead(204);
this.res.end();
};

JsonResponder.prototype.resetContent = function(){
this.res.writeHead(205);
this.res.end();
};

JsonResponder.prototype.movedPermanently = function(url){
url = url || '';
this.res.setHeader('Location', url);
this.res.writeHead(301);
this.res.end();
};

JsonResponder.prototype.found = function(url){
url = url || '';
this.res.setHeader('Location', url);
this.res.writeHead(302);
this.res.end();
};

JsonResponder.prototype.redirect = function(url){
this.found(url);
};

JsonResponder.prototype.OPTIONS = function(methods){
this.res.setHeader('Allow', methods.join(","));
this.res.writeHead(200);
return this.res.end(JSON.stringify({"allowed methods" : methods}));
};


module.exports = JsonResponder;
125 changes: 0 additions & 125 deletions lib/JsonResponder.js

This file was deleted.

9 changes: 4 additions & 5 deletions package.json
Expand Up @@ -10,7 +10,7 @@
"http",
"hypermedia"
],
"version": "0.2.4",
"version": "0.3.0",
"bugs": {
"url": "https://github.com/cainus/json-status/issues"
},
Expand All @@ -23,12 +23,11 @@
"dependencies": {
},
"devDependencies": {
"coveralls": "2.10.0",
"jshint": "2.4.4",
"istanbul": "0.2.7",
"request": "2.19.0",
"mocha-lcov-reporter": "0.0.1",
"jscoverage": "0.3.6",
"coveralls": "2.0.13",
"mockery": "1.1.2",
"hottap": "1.0.0",
"mocha": "1.8.1",
"connect": "~2.7.11",
"should": "1.1.0"
Expand Down
2 changes: 2 additions & 0 deletions test/JsonResponder.js → test/index.js
Expand Up @@ -195,6 +195,8 @@ describe("JsonStatus", function(){
var responder = new JsonStatus({}, fakeRes);
responder.created("SOMEURL");
fakeRes.headers.Location.should.equal("SOMEURL");
should.not.exist(fakeRes.headers['content-type']);
// no content-type when there's no body!
fakeRes.status.should.equal(201);
fakeRes.ended.should.equal(true);
});
Expand Down

0 comments on commit baaf6ca

Please sign in to comment.