Permalink
Browse files

smarter onScreen w/ array return types and pass()

  • Loading branch information...
1 parent 3c8e0fc commit 500304228dbc62795de47c107a73a02e5c91197a @dantebronto committed Jan 24, 2011
Showing with 92 additions and 33 deletions.
  1. +22 −0 examples/misc/app.js
  2. +29 −25 lib/picard/request.js
  3. +6 −1 lib/picard/routing.js
  4. +2 −7 lib/picard/server.js
  5. +33 −0 spec/misc/misc_spec.js
View
@@ -3,6 +3,7 @@ require('../../lib/picard').
// Many top-level functions return 'this', allowing
// for chaining of routes without calling Picard.globalize()
+// process a posted form
post('/with_params', function(params){
return { text: '<h1>' + params.foo + ' ' + params.baz + '</h1>' }
}).
@@ -20,4 +21,25 @@ del('/fire/:number', function(params){
return { text: text }
}).
+get('/returns_string', function(){
+ return 'this is the response'
+}).
+
+get('/returns_triplet', function(){
+ headers = [
+ [ 'content-type', 'application/foo' ],
+ [ 'custom-header', 'cool']
+ ]
+ // scope can be an array like [status, headers, body]
+ return [201, headers, 'this is the response']
+}).
+
+get('/passing/:blah', function(env){
+ env.pass() // pass to the next matching route handler
+}).
+
+get('/passing/to_me', function(){
+ return 'passed from previous route'
+}).
+
start()
View
@@ -5,7 +5,7 @@ var sys = require('sys'),
merge = require('./merge'),
Routes = require('./routing')
-var requestExtensions = {
+var RequestExtensions = {
cookie: function(name, val, options){
if ( val === undefined )
return this.cookies[name]
@@ -26,23 +26,28 @@ var requestExtensions = {
sys.puts(ex.stack)
},
onScreen: function(scope){
- if( this.response.finished ){ return }
-
+ var req = this,
+ type = toString.call(scope)
+
+ if( req.response.finished ) return
+
if ( scope == null )
scope = { status: 404, body: "<h1> 404 Not Found </h1>" }
-
- var req = this
-
- if(typeof(scope) == 'string')
+ else if ( type == '[object String]' )
scope = { text: scope }
+ else if ( type == '[object Array]' )
+ scope = { status: scope[0], headers: scope[1], body: scope[2] }
scope.status = scope.status || 200
scope.headers = scope.headers || []
scope.body = scope.text || scope.body || ''
scope.encoding = scope.encoding || 'utf8'
- scope.headers.push([ 'Server', req.picardServer || 'Picard ' + server.version ])
- scope.headers.push([ 'Content-Type', scope.type || 'text/html' ])
+ if (scope.headers.length == 0 ){
+ scope.headers.push([ 'Server', req.picardServer || 'Picard ' + server.version ])
+ scope.headers.push([ 'Content-Type', scope.type || 'text/html' ])
+ }
+
scope.headers = req.setCookies(scope.headers)
if ( scope.status == 500 && !scope.template )
@@ -53,16 +58,16 @@ var requestExtensions = {
req.log(scope)
},
log: function(scope){
- sys.puts((this._method || this.method).toUpperCase() + ' ' + this.parsedUrl().pathname + ' ' + scope.status)
+ sys.puts([
+ (this._method || this.method).toUpperCase(), ' ',
+ this.parsedUrl().pathname, ' ', scope.status
+ ].join(''))
},
parsedUrl: function() {
- if ( !('url' in this) )
- return;
- var parsed = url.parse(this.url, true);
- this.parsedUrl = function() {
- return parsed;
- };
- return parsed;
+ if ( !('url' in this) ) return
+ var parsed = url.parse(this.url, true)
+ this.parsedUrl = function() { return parsed }
+ return parsed
},
redirect: function(location){
return {
@@ -81,7 +86,7 @@ var requestExtensions = {
},
extractFormParams: function(chunk){
try {
- if( chunk == undefined ) { return }
+ if( chunk == undefined ) return
var chunks = chunk.toString().replace(/\+/g, '%20').split('&')
this.body = ('body' in this) ? this.body + chunk : chunk;
@@ -110,9 +115,8 @@ var requestExtensions = {
try {
this.cookies = {}
var self = this
- var cookieHeader = self.headers["cookie"]
+ var cookieHeader = self.headers['cookie']
if (cookieHeader){
-
cookieHeader.split("; ").forEach(function(cookie){
var parts = cookie.split("=")
self.cookie(parts[0], decodeURIComponent(parts[1]), { preset: true })
@@ -122,20 +126,20 @@ var requestExtensions = {
this.handleException(ex)
}
},
- resolve: function(){
+ pass: function(){
try {
+ this.parseCookies()
var scope = Routes.executeCallback(this)
-
+
if( scope == 'static' )
scope = doc.serveStatic(this)
- if ( scope == null )
+ if ( scope == null || scope == undefined )
return
this.onScreen(scope)
} catch(ex) {
this.handleException(ex)
}
-
},
setCookies: function(headers){
var ret, name, options
@@ -161,4 +165,4 @@ var requestExtensions = {
}
// extend abstract parent of http.ServerRequest
-merge(require('http').IncomingMessage.prototype, requestExtensions)
+merge(require('http').IncomingMessage.prototype, RequestExtensions)
View
@@ -20,12 +20,17 @@ var Routes = {
executeCallback: function(request){
var routesByType = Routes.byRestType(request)
var route, matches
-
+
for(var i=0, l = routesByType.length; i < l; i++){
route = routesByType[i]
matches = request.parsedUrl().pathname.match(route.path)
if( matches ){ // incoming request matches route
+ if ( request.route ){
+ if ( request.route == route )
+ request.route = null
+ continue
+ }
request.extractRouteParams(route, matches)
try {
request.route = route
View
@@ -8,13 +8,8 @@ var Server = {
request.response = response
request
- .on('data', function(chunk){
- request.extractFormParams(chunk)
- })
- .on('end', function(){
- request.parseCookies()
- request.resolve()
- })
+ .on('data', request.extractFormParams)
+ .on('end', request.pass)
}).
listen(this.env.port)
View
@@ -1,3 +1,36 @@
+describe('GET', function(){
+
+ it('should allow a triplet response', function(){
+ testReq('GET', '/returns_triplet', function(status, headers, body){
+ expect(status).toEqual(201)
+ expect(body).toEqual('this is the response')
+ expect(headers['content-type']).toEqual('application/foo')
+ expect(headers['custom-header']).toEqual('cool')
+ asyncSpecDone()
+ })
+ asyncSpecWait()
+ })
+
+ it('should allow a string response', function(){
+ testReq('GET', '/returns_string', function(status, headers, body){
+ expect(status).toEqual(200)
+ expect(body).toEqual('this is the response')
+ asyncSpecDone()
+ })
+ asyncSpecWait()
+ })
+
+ it('should allow route passing', function(){
+ testReq('GET', '/passing/to_me', function(status, headers, body){
+ expect(status).toEqual(200)
+ expect(body).toEqual('passed from previous route')
+ asyncSpecDone()
+ })
+ asyncSpecWait()
+ })
+
+})
+
describe('POST', function(){
it('should accept parameters', function(){

0 comments on commit 5003042

Please sign in to comment.