Permalink
Browse files

refactored views to avoid express monkey patches.

test views against example data and against live site.
  • Loading branch information...
1 parent 039499b commit 64b569eb93b463dad97e9029b102de8b9f30dd59 @dominictarr committed Jun 6, 2011
Showing with 345 additions and 44 deletions.
  1. +22 −0 app-setup.js
  2. +1 −1 package.json
  3. +36 −25 server.js
  4. +1 −0 setup.js
  5. +104 −0 test/live-views.asynct.js
  6. +1 −1 test/test-with-vows.asynct.js
  7. +124 −0 test/view.asynct.js
  8. +2 −2 username.jade
  9. +37 −0 view.js
  10. +4 −4 views/github.jade
  11. +1 −0 views/hello.jade
  12. +1 −1 views/layout.jade
  13. +4 −4 views/result.jade
  14. +5 −4 views/status.jade
  15. +1 −1 views/test.jade
  16. +1 −1 views/user.jade
View
22 app-setup.js
@@ -0,0 +1,22 @@
+var express = require('express')
+ , fs = require('fs')
+ , app = express.createServer()
+ , package = JSON.parse(fs.readFileSync(__dirname + '/package.json'))
+
+module.exports = function (config){
+ app.configure(function(){
+ app.set('views', __dirname + '/views');
+ app.set('view engine', 'jade');
+ app.set('view options', {
+ testbedPackage: package,
+ status: 'success', //sets the tab icon
+ basedir: config.basedir
+ });
+ app.use(express.bodyParser());
+ app.use(express.methodOverride());
+ app.use(express.static(__dirname + '/public'));
+ app.use(app.router);
+ });
+
+ return app
+}
View
2 package.json
@@ -14,7 +14,7 @@
"node": ">= 0.4.7"
},
"dependencies": {
- "meta-test": ">= 0.0.7",
+ "meta-test": ">= 0.0.9",
"it-is": "0.0.x",
"express": "= 2.3.10",
"eyes": "= 0.1.6",
View
61 server.js
@@ -1,53 +1,41 @@
#!/usr/bin/env node
-var express = require('express')
- , app = express.createServer()
- , testbed = new (require('./testbed'))(process.cwd() + '/workspace')
+var testbed = new (require('./testbed'))(process.cwd() + '/workspace')
+ , appSetup = require('./app-setup')
, request = require('request')
, w = require('winston')
- , fs = require('fs')
, eyes = require('eyes')
, render = require('render')
, url = require('url')
- , database = 'testbed'
, db
, config
- , package = JSON.parse(fs.readFileSync(__dirname + '/package.json'))
w.cli()
w.info('TESTBED')
w.info(new Date)
if(!module.parent){
config = require('./setup').deploy()
- app.listen(config.port);
} else {
config = require('./setup').test()
}
+ var app = appSetup(config)
+
+ if(!module.parent)
+ app.listen(config.port);
+
+
db = require('./initialize')(config.database,function (err,db){
if(err){
w.error("DATABASE SETUP ERROR")
throw err
}
- w.info("DATABASE '" + database + "' IS READY")
+ w.info("DATABASE '" + config.database + "' IS READY")
})
-app.configure(function(){
- app.set('views', __dirname + '/views');
- app.set('view engine', 'jade');
- app.set('view options', {
- package: package,
- status: 'success', //sets the tab icon
- basedir: config.basedir
- });
- app.use(express.bodyParser());
- app.use(express.methodOverride());
- app.use(express.static(__dirname + '/public'));
- app.use(app.router);
-});
-
-function save (repo){
+
+function save (repo){ //pull this out also.
if(repo._id && !repo.saving){
repo.saving = true
@@ -87,12 +75,15 @@ function save (repo){
app.post('/', function (req,res){
+ //pull all of this out into a repo controller.
+
if(!req.body)
return res.send ({error: "Expected payload: property"})
try{
var payload = JSON.parse(req.body.payload)
} catch (err){
w.error('could not parse POST JSON')
+ w.statusCode = 400
return res.send ({
error: "was not valid JSON",
was: req.body.payload,
@@ -109,6 +100,7 @@ app.post('/', function (req,res){
repo.post = payload
repo.on('change',function (event){
+ //log
console.log([repo.username,repo.project].join('/'),[].shift.call(arguments))
while(arguments.length)
console.log([].shift.call(arguments))
@@ -117,17 +109,31 @@ app.post('/', function (req,res){
})
repo.integrate(function (err,data){
+ //log
if(err){
return res.send({error: err, reason: "could not connect to github or npm", data: data})
}
res.send(data)
})
})
+/*
+controller gets req and a callback, through which it passes it's data to renderer
+
+this would at least make it possible to decouple the controller
+
+how to handle errors?
+
+first arg is error.
+views for errors are defined once for the handler
+*/
+
+//app.get('/path', handleRoute(controller, renderer))
+
app.get('/:username/:project/:commit', function (req,res){
db.get([req.params.username, req.params.project, req.params.commit].join(','),
function (err,data){
- res.render('result',data)
+ res.render('result',{self:data})
})
})
@@ -142,11 +148,16 @@ function summary(opts,res){
data.rows.sort(function (x,y){
return x.value.time < y.value.time ? 1 : -1
})
- res.render('user',data)
+ res.render('user',{self:data})
})
}
+//replace this with a function that calls the decoupled controller with just
+//params, query,
+//and that calls back
+//with an the object ready for the view.
+
app.get('/:username/:project', function (req,res){
var key =
View
1 setup.js
@@ -3,6 +3,7 @@ var w = require('winston')
, eyes = require('eyes')
, exec = require('child_process').exec
, fs = require('fs')
+ , config
, defaults = {
host: 'http://localhost',
port: 3000,
View
104 test/live-views.asynct.js
@@ -0,0 +1,104 @@
+var app = require('../app-setup')(require('../setup').deploy())
+ , port = Math.round(10000 + Math.random() * 40000)
+ , request = require('request')
+ , http = require('http')
+ , render = require('render')
+ , client
+ , res
+
+function getSummary (callback){
+
+ request({uri: 'http://testbedjs.org:5985/testbed1/_design/all/_view/summary?reduce=false'}
+ , function (err,res,data){
+
+ console.log('retrive summary')
+
+ callback(err,JSON.parse(data))
+ })
+}
+
+function getAll (callback){
+
+ request({uri: 'http://testbedjs.org:5985/testbed1/_all_docs?include_docs=true'}
+ , function (err,res,data){
+ callback(err,JSON.parse(data))
+ })
+}
+
+
+//an UGLY way to get the reponse object
+
+exports.__setup = function (test){
+ console.log('setup test')
+
+ app.get('/',function (req,_res){
+ res = _res
+ console.log('setup complete')
+
+ test.done()
+ })
+
+ app.listen(port, function (){
+ client = http.get({port: port})
+ })
+
+}
+
+function partial(view,object, callback){
+ res.partial(view,object,function (err,data){
+ if(err)
+ throw err
+ callback()
+ })
+}
+
+function view(view, object, callback){
+ var clean = render.ct(object)
+ console.log('check view')
+ res.render(view,{self: object},function (err,data){
+ if(err){
+ console.log('***********************')
+ console.log('ERROR RENDERING VIEW FOR OBJECT:')
+ console.log(clean)
+ console.log(err.stack)
+ console.log('***********************')
+ throw err
+ }
+ callback()
+ })
+}
+
+exports['summary view'] = function (test){
+
+ getSummary(function (err,data){
+ if(err)
+ throw err
+ console.log(data)
+ view('user', data,test.done)
+
+ })
+}
+
+exports ['result view'] = function (test) {
+
+ getAll(function (err,examples){
+
+ function next () {
+ var example = examples.shift()
+
+ if(!example)
+ return test.done()
+
+ view('result', example, next)
+ }
+ next()
+
+ })
+}
+
+
+exports.__teardown = function (test){
+ console.log('TEARDOWN')
+ client.abort()
+ app.close()
+}
View
2 test/test-with-vows.asynct.js
@@ -13,7 +13,7 @@ exports.__setup = function (test){
exports ['integrate a repo that uses vows'] = function (test){
- var webservice = testbed.Repo('Marak','webservice.js')
+ var webservice = testbed.Repo('dominictarr','webservice.js')
, events = ['clone', 'init', 'update', 'tested']
, changes = 0
View
124 test/view.asynct.js
@@ -0,0 +1,124 @@
+var app = require('../app-setup')(require('../setup').deploy())
+ , port = Math.round(10000 + Math.random() * 40000)
+ , http = require('http')
+ , render = require('render')
+ , client
+ , res
+
+//an UGLY way to get the reponse object
+
+exports.__setup = function (test){
+
+ app.get('/',function (req,_res){
+ res = _res
+
+ test.done()
+ })
+
+ app.listen(port, function (){
+ client = http.get({port: port})
+ })
+
+}
+
+
+/*
+
+partials are kind dumb.
+
+I don't like it how they are magically given the name of the partial,
+
+'this' would be more idiomatic.
+
+and it's also very bad how partial behaves different whether it's
+rendering an array or a object. if you want it to render your array,
+you should explicitly call partials or allPartials.
+
+implicit is not as good as explicit.
+
+*/
+
+function partial(view,object, callback){
+ res.partial(view,object,function (err,data){
+ if(err)
+ throw err
+ callback()
+ })
+}
+
+function view(view,object, callback){
+ var clean = render.ct(object)//have to stringify first to avoid express monkeys.
+
+ res.render(view,{self: object},function (err,data){
+ if(err){
+ console.log('***********************')
+ console.log('ERROR RENDERING VIEW FOR OBJECT:')
+ console.log(clean)
+ console.log(err.stack)
+ console.log('***********************')
+ throw err
+ }
+ callback()
+ })
+}
+
+
+exports ['error view'] = function (test){
+ var examples = [
+ 1,
+ false,
+ new Error(),
+ (function (){//stack overflow
+ function overflow(){overflow()}
+ try {
+ overflow()
+ } catch(err) {
+ return err
+ }
+ })(),
+ {error:'couch error', message: 'have no stack trace'}
+ ]
+ partial('error',examples,test.done)
+}
+
+exports ['summary view'] = function (test){
+
+ var example =
+ { rows:
+ [ { key: ['username', 'project','32r98349f834598t93423ur']
+ , value:{
+ commit:"95f136ddccd643099585176028fba91339359efe"
+ , status:"error"
+ , time:"2011-06-06T09:59:33.899Z"
+ , total:21
+ , passes:19
+ }
+ }
+ ]
+ }
+ view('user',example,test.done)
+
+}
+
+exports ['result view'] = function (test) {
+ var fs = require ('fs')
+ var examples =
+ JSON.parse(fs.readFileSync(__dirname + '/data/testbed-migrated.json'))
+
+ function next () {
+ var example = examples.shift()
+
+ if(!example)
+ return test.done()
+
+ view('result', example, next)
+ }
+ next()
+}
+
+exports.__teardown = function (test){
+ console.log('TEARDOWN')
+ client.abort()
+ app.close()
+
+}
View
4 username.jade
@@ -1,4 +1,4 @@
-h1= 'Testbed/' + rows[0].key[0]
- - rows.forEach(function (e){
+h1= 'Testbed/' + self.rows[0].key[0]
+ - self.rows.forEach(function (e){
h3= e.key.slice(1).join('/') + ' - ' + e.value
- })
View
37 view.js
@@ -0,0 +1,37 @@
+var express = require('express')
+ , app = express.createServer()
+ , http = require('http')
+app.configure(function(){
+ app.set('views', __dirname + '/views');
+ app.set('view engine', 'jade');
+ app.set('view options', {
+ testbedPackage: {},
+ status: 'success', //sets the tab icon
+ basedir: __dirname//{} //config.basedir
+ });
+});
+
+/*res.render('empty',{}, function (err,data){
+ if(err)
+ throw err
+
+ console.log(data)
+})*/
+
+app.get('/', function (req,res){
+
+ res.render('hello',{}/*,function (err,html){
+ if(err)
+ throw err
+ console.log(html)
+ }*/)
+})
+
+app.listen(8001,function (){
+
+})
+setTimeout(function (){
+ http.get({host:'localhost', port:8001, path:'/'}, function (){
+// app.close()
+ })
+},100)
View
8 views/github.jade
@@ -1,7 +1,7 @@
div(class= 'github content')
div(class= 'header')
- a(href= repository.url)= repository.url
- span(class= 'language right')= '('+ repository.language +')'
- div(class= 'description')= repository.description
+ a(href= self.repository.url)= self.repository.url
+ span(class= 'language right')= '('+ self.repository.language +')'
+ div(class= 'description')= self.repository.description
hr
- div!= partial('./commit', commits)
+ div!= partial('./commit', self.commits || [])
View
1 views/hello.jade
@@ -0,0 +1 @@
+h1 hello
View
2 views/layout.jade
@@ -11,7 +11,7 @@ html
!= partial('./forkme')
h1
a(href='/') Testbed
- span(class='secondary')= 'v' + package.version
+ span(class='secondary')= 'v' + testbedPackage.version
span
| Continuous Integration for nodejs
div#main!= body
View
8 views/result.jade
@@ -1,13 +1,13 @@
h3
- var sofar = []
- - ;_id.split(',').forEach(function (e){
+ - ;self._id.split(',').forEach(function (e){
- sofar.push(e)
span /
a(href='/' + sofar.join('/'))=e
- })
-!= partial('./github', post)
+!= partial('./github', {self:self.post})
div(class='content')
- h3!= partial('./status', report)
- div!= partial('./test', report.tests)
+ h3!= partial('./status', {self:self.report})
+ div!= partial('./test', self.report.tests || [])
View
9 views/status.jade
@@ -1,8 +1,9 @@
- var s = []
-- var status = tests.reduce(function (x,y) {
-- x.tests.forEach(function (e){s.push(e.status)})
-- return x.status < y.status ? x : y
-- },{status:'unran', tests: []}).status
+- if(self.tests)
+ - var status = self.tests.reduce(function (x,y) {
+ - x.tests.forEach(function (e){s.push(e.status)})
+ - return x.status < y.status ? x : y
+ - },{status:'unran', tests: []}).status
//
span(class= status)= status
span(class= 'right')
View
2 views/test.jade
@@ -1,6 +1,6 @@
div(class = 'tests')
span(class= test.status + ' status right')= test.status
- =' '+ test.name.replace(basedir ,'')
+ =' '+ (test.name || test.filename || '').replace(basedir ,'')
- if ('success' != test.status)
div(class= 'stacktrace')
!= partial ('error', test.failures || test.errors)
View
2 views/user.jade
@@ -6,7 +6,7 @@ TABLE.content
td status
td %
td when?
- - rows.forEach(function (e,k){
+ - self.rows.forEach(function (e,k){
- var i = 0
tr(class= 'test-commit ' + ((k % 2) ? 'odd' : 'even'))
- var sofar = []

0 comments on commit 64b569e

Please sign in to comment.