Browse files

upgraded to oneone 0.3.0. got coverage working. broke some stuff. :\

  • Loading branch information...
1 parent e053146 commit 254a61538364c3ca30fce63ef405235bc1574f8e @cainus committed Oct 6, 2012
View
4 .gitignore
@@ -1,2 +1,4 @@
-/node_modules
+node_modules
npm-debug.log
+lib-cov
+coverage.html
View
10 Makefile
@@ -1,4 +1,12 @@
+REPORTER = spec
test:
- @NODE_ENV=test ./node_modules/.bin/mocha --timeout 3000
+ @NODE_ENV=test ./node_modules/.bin/mocha -b --reporter $(REPORTER)
+
+lib-cov:
+ jscoverage lib lib-cov
+
+test-cov: lib-cov
+ @PERCOLATOR_COVERAGE=1 $(MAKE) test REPORTER=html-cov > coverage.html
+ rm -rf lib-cov
.PHONY: test
View
15 index.js
@@ -1 +1,14 @@
-module.exports = require('./percolator');
+var dir = './lib/';
+if (process.env.PERCOLATOR_COVERAGE){
+ dir = './lib-cov/';
+}
+var helperDir = dir + 'ContextHelpers/';
+
+exports.JsonResponder = require(dir + 'JsonResponder');
+exports.StatusManager = require(dir + 'StatusManager');
+exports.UriUtil = require(dir + 'UriUtil');
+
+exports.AuthenticateContextHelper = require(helperDir + 'Authenticate');
+exports.BodyContextHelper = require(helperDir + 'Body');
+exports.FetchContextHelper = require(helperDir + 'Fetch');
+exports.Percolator = require(dir + 'Percolator');
View
0 ContextHelpers/Authenticate.js → lib/ContextHelpers/Authenticate.js
File renamed without changes.
View
0 ContextHelpers/Body.js → lib/ContextHelpers/Body.js
File renamed without changes.
View
0 ContextHelpers/Fetch.js → lib/ContextHelpers/Fetch.js
File renamed without changes.
View
77 lib/JsonResponder.js
@@ -0,0 +1,77 @@
+var EventEmitter = require('events').EventEmitter;
+var _ = require('underscore');
+
+var JsonResponder = function(req, res){
+ this.req = req;
+ this.res = res;
+};
+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'}
+};
+
+
+/* set methods on the JsonResponder for every kind of error that could occur. */
+_.each(errors, function(v, k){
+ JsonResponder.prototype[k] = function(detail){
+ var obj = {"error" : v};
+ obj.error.detail = detail || {};
+ this.res.setHeader('Content-Type', 'application/json');
+ this.res.writeHead(v.type);
+ var out = JSON.stringify(obj);
+ this.res.end(out);
+ this.emit("error", { req : this.req, res : this.res, type : v.type, message : v.message, detail : detail } );
+ };
+});
+
+JsonResponder.prototype.created = function(url){
+ url = url || '';
+ this.res.setHeader('Location', url);
+ this.res.writeHead(201);
+ this.res.end();
+};
+
+JsonResponder.prototype.accepted = function(){
+ this.res.writeHead(202);
+ this.res.end();
+};
+
+JsonResponder.prototype.movedPermanently = function(url){
+ this.redirect(url);
+};
+
+JsonResponder.prototype.redirect = function(url){
+ url = url || '';
+ this.res.setHeader('Location', url);
+ this.res.writeHead(301);
+ this.res.end();
+};
+
+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;
View
21 percolator.js → lib/Percolator.js
@@ -1,14 +1,15 @@
var Reaper = require('reaper').Reaper;
-var UriUtil = require('./uriUtil').UriUtil;
var EventEmitter = require('events').EventEmitter;
-var StatusManager = require('./StatusManager').StatusManager;
-var JsonResponder = require('./JsonResponder');
-var fetchContextHelper = require('./ContextHelpers/Fetch');
-var authenticateContextHelper = require('./ContextHelpers/Authenticate');
-var bodyContextHelper = require('./ContextHelpers/Body');
+var index = require('../index');
+var JsonResponder = index.JsonResponder;
+var bodyContextHelper = index.BodyContextHelper;
+var fetchContextHelper = index.FetchContextHelper;
+var AuthenticateContextHelper = index.AuthenticateContextHelper;
+var UriUtil = index.UriUtil;
+var StatusManager = index.StatusManager;
var _ = require('underscore');
var fs = require('fs');
-var Server = require('oneone').Server;
+var Server = require('oneone');
Percolator = function(options){
@@ -72,7 +73,7 @@ Percolator.prototype.defaultContextHandler = function(context, handler, cb){
var that = this;
var req = context.req;
var res = context.res;
- authenticateContextHelper(context, handler, function(){
+ AuthenticateContextHelper(context, handler, function(){
fetchContextHelper(context, handler, function(){
if (!!that.options.parseBody){
that.mediaTypes.connectMiddleware(context)(req, res, function(err){
@@ -144,8 +145,8 @@ Percolator.prototype._getMethods = function(resource){
};
// route a directory call the callback afterward
-Percolator.prototype.routeDirectory = function(directory, cb){
- this.newServer.routeDirectory(directory, cb);
+Percolator.prototype.routeDirectory = function(directory, path, cb){
+ this.newServer.routeDirectory(directory, path, cb);
};
View
28 lib/StatusManager.js
@@ -0,0 +1,28 @@
+_ = require('underscore');
+JsonResponder = require('../index').JsonResponder;
+var EventEmitter = require('events').EventEmitter;
+
+var StatusManager = function(){
+ this.registry = {};
+};
+
+StatusManager.prototype = Object.create(EventEmitter.prototype);
+
+StatusManager.prototype.register = function(contentType, responder){
+ this.registry[contentType] = responder;
+};
+
+StatusManager.prototype.createResponder = function(req, res){
+ // TODO make this do conneg and pick a responder from the registry!
+
+ // TODO make default text/plain, text/html, application/xml,
+ // application/octet-sctream, form-url-encoded responders
+ var responder = new JsonResponder(req, res);
+ var that = this;
+ responder.on('error', function(data){
+ that.emit('error', data);
+ });
+ return responder;
+};
+
+module.exports = StatusManager;
View
151 lib/UriUtil.js
@@ -0,0 +1,151 @@
+var nodeUrl = require('url');
+var querystring = require('querystring');
+var _ = require('underscore');
+
+var UriUtil = function(router, urlstr, protocol, host){
+ this._router = router;
+ this._self = urlstr;
+ this._params = null;
+ this._protocol = protocol || 'http';
+ this._host = host || 'localhost';
+};
+
+
+UriUtil.prototype.absolute = function(path){
+ if (path[0] == '/'){
+ path = path.substring(1);
+ }
+ return this._protocol + "://" + this._host + '/' + path;
+};
+
+UriUtil.prototype.urlEncode = function(str){
+ return querystring.escape(str);
+};
+
+UriUtil.prototype.urlDecode = function(str){
+ return querystring.unescape(str);
+};
+
+UriUtil.prototype.query = function(inUrl){
+ var url = inUrl || this._self;
+ var parsed = nodeUrl.parse(url);
+ if (!!parsed.search){
+ var qstr = parsed.search.substring(1);
+ return querystring.parse(qstr);
+ }
+ return {};
+};
+
+UriUtil.prototype.queryString = function(obj){
+ var that = this;
+ var pairs = _.map(obj, function(v, k){
+ return that.urlEncode(k) + '=' + that.urlEncode(v);
+ });
+ return '?' + pairs.join('&');
+};
+
+UriUtil.prototype.pathJoin = function(){
+ // put a fwd-slash between all pieces and remove any redundant slashes
+ // additionally remove the trailing slash
+ var pieces = _.flatten(_.toArray(arguments));
+ var first = nodeUrl.parse(pieces[0]);
+ var prefix = '/';
+ if (!!first.protocol){
+ pieces[0] = first.path;
+ prefix = first.protocol + '//' + first.host;
+ }
+ var joined = pieces.join('/').replace(/\/+/g, '/');
+ joined = joined.replace(/\/$/, '');
+ if (joined[0] === '/'){
+ joined.substring(1);
+ }
+ joined = prefix + joined;
+ return joined;
+};
+
+UriUtil.prototype.links = function(){
+ var kids = this.namedKids();
+ var links = {};
+ _.each(kids, function(v, k){
+ links[k] = { href : v};
+ });
+ links.self = {href : this.absolute(this._self)};
+ try {
+ links.parent = {href : this.absolute(this.parent())};
+ } catch (ex){
+ if (ex.name != 'NoParentUrl'){
+ throw ex;
+ }
+ }
+ return links;
+};
+
+UriUtil.prototype.parent = function(inUrl){
+ var url = inUrl || this._self;
+ return this._router.getParentUrl(url);
+};
+
+UriUtil.prototype.namedKids = function(inUrl){
+ var url = inUrl || this._self;
+ var kids = this._router.getNamedChildUrls(url);
+ var that = this;
+ _.each(kids, function(v, k){
+ kids[k] = that.absolute(v);
+ });
+ return kids;
+};
+UriUtil.prototype.kids = function(inUrl){
+ var url = inUrl || this._self;
+ return this._router.getChildUrls(url);
+};
+
+UriUtil.prototype.parse = function(inUrl){
+ return nodeUrl.parse(this._self);
+
+};
+
+UriUtil.prototype.get = function(nameOrPath, varDict){
+ if (!!nameOrPath){
+ if (!!varDict){
+ return this.absolute(this._router.getUrl(nameOrPath, varDict));
+ }
+ return this.absolute(this._router.getUrl(nameOrPath));
+ }
+ return this._self;
+};
+
+UriUtil.prototype.self = function(){
+ return this.absolute(this._self);
+};
+
+UriUtil.prototype.param = function(key, defaultValue){
+ var value = this.params()[key];
+ if (!!value) {
+ return value;
+ }
+ return defaultValue;
+};
+
+UriUtil.prototype.params = function(inUrl){
+ if (!!inUrl){
+ return this._router.pathVariables(inUrl);
+ }
+ if (!!this._params){
+ return this._params;
+ }
+ return this._router.pathVariables(this._self);
+};
+
+UriUtil.prototype.help = function(){
+ console.log("HELP!");
+ var retval = {};
+ retval = _.extend(retval, {params : this.params()});
+ retval = _.extend(retval, {links : this.links()});
+ retval = _.extend(retval, {parse : this.parse()});
+ retval = _.extend(retval, {query : this.query()});
+ retval = _.extend(retval, {kids : this.kids()});
+ retval = _.extend(retval, {namedKids : this.namedKids()});
+ return retval;
+};
+
+module.exports = UriUtil;
View
0 mediaTypes/json.js → lib/mediaTypes/json.js
File renamed without changes.
View
0 mediaTypes/xml.js → lib/mediaTypes/xml.js
File renamed without changes.
View
2 package.json
@@ -19,7 +19,7 @@
"dependencies": {
"underscore" : "1.3.3",
"reaper" : "0.2.3",
- "oneone" : "0.2.1"
+ "oneone" : "0.3.0"
},
"devDependencies" : {
"mockery" : "1.1.2",
View
2 test/AuthenticateContextHelper.js
@@ -1,5 +1,5 @@
var should = require('should');
-var fch = require('../ContextHelpers/Authenticate');
+var fch = require('../index').AuthenticateContextHelper;
describe("AuthenticateContextHelper", function(done){
it ("does nothing if the context has no authenticate method", function(done){
View
2 test/BodyContextHelper.js
@@ -1,5 +1,5 @@
var should = require('should');
-var bch = require('../ContextHelpers/Body');
+var bch = require('../index').BodyContextHelper;
describe("BodyContextHelper", function(){
View
2 test/FetchContextHelper.js
@@ -1,5 +1,5 @@
var should = require('should');
-var fch = require('../ContextHelpers/Fetch');
+var fch = require('../index').FetchContextHelper;
describe("FetchContextHelper", function(done){
it ("does nothing if the context has no fetch method", function(done){
View
2 test/JsonResponder.js
@@ -1,5 +1,5 @@
var should = require('should');
-var JsonResponder = require('../JsonResponder');
+var JsonResponder = require('../index').JsonResponder;
var FakeResponse = function(){
this.status = null;
View
9 test/percolator.js → test/Percolator.js
@@ -1,15 +1,15 @@
var should = require('should');
var hottap = require('hottap').hottap;
var _ = require('underscore');
-var Percolator = require('../percolator');
+var Percolator = require('../index').Percolator;
function closeServer(server, cb){
if (!!server){
try {
server.close();
} catch(ex){
-
+
}
}
return cb();
@@ -28,6 +28,7 @@ describe('Percolator', function(){
closeServer(this.server, done);
});
+
it("has default error handlers for 404s", function(done){
var that = this;
var url = "http://localhost:3000/DOES_NOT_EXIST";
@@ -309,6 +310,10 @@ describe('Percolator', function(){
});*/
describe('#ctor', function(){
+ it("can be created", function(){
+ var server = new Percolator({port : 3000});
+ should.exist(server);
+ });
it ("can override the default port", function(done){
var that = this;
var port = 3001; // set non-default here
View
10 test/StatusManager.js
@@ -0,0 +1,10 @@
+
+var should = require('should');
+var StatusManager = require('../index').StatusManager;
+
+describe("StatusManager", function(){
+ it ("can be constructed", function(){
+ var sm = new StatusManager();
+ should.exist(sm);
+ });
+});
View
3 test/uriUtil.js → test/UriUtil.js
@@ -2,7 +2,7 @@ var should = require('should');
var mockery = require('mockery');
var hottap = require('hottap').hottap;
var _ = require('underscore');
-var UriUtil = require('../uriUtil').UriUtil;
+var UriUtil = require('../index').UriUtil;
/*
TODO?
@@ -106,7 +106,6 @@ describe('UriUtil', function(){
var u = new UriUtil(router, '[path]');
u.links().should.eql({self : {href : 'http://localhost/[path]'},
somechild : {href : 'http://localhost/child[path]'}});
-
calledNamedChildUrls.should.equal(true);
calledParentUrls.should.equal(true);
});
View
6 test_server.js
@@ -1,5 +1,5 @@
var _ = require('underscore');
-var Percolator = require('./percolator');
+var Percolator = require('./index').Percolator;
// TODO collections proof-of-concept - POST, PUT, DELETE
// TODO make status man do conneg
@@ -27,14 +27,14 @@ server.onRequest(function(handler, context, cb){
});
var resourceDir = __dirname + '/test/test_fixtures/resources';
-server.routeDirectory(resourceDir, function(err){
+server.routeDirectory(resourceDir, app.resourcePath, function(err){
console.log("routed resources in " + resourceDir);
server.route('/inside',
{ GET : function($){
$.res.end("muahahah!");
}
- }).as('inside');
+ });
if (err) {
console.log("Routing error");

0 comments on commit 254a615

Please sign in to comment.