Skip to content

Commit

Permalink
[test] Add tests (per #14)
Browse files Browse the repository at this point in the history
- Added tests for both the server and proxy logic
- Added script for generating code coverage
- Added [email protected] as a dev dependency
  • Loading branch information
evanlucas committed Apr 6, 2014
1 parent 907868c commit e0cfa64
Show file tree
Hide file tree
Showing 18 changed files with 1,342 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ results

npm-debug.log
node_modules
coverage.*
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "An intelligent routing proxy for npm with support for: private, whitelisted, and blacklisted packaged ",
"main": "lib/index.js",
"scripts": {
"test": "npm install --reg http://localhost:2618"
"test": "node test/test.js",
"cover": "./scripts/cover.sh && ./scripts/results.js"
},
"repository": {
"type": "git",
Expand All @@ -28,5 +29,8 @@
"director": "~1.2.2",
"http-proxy": "~1.0.1",
"request": "~2.33.0"
},
"devDependencies": {
"mocha": "^1.18.2"
}
}
14 changes: 14 additions & 0 deletions scripts/cover.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

which jscoverage > /dev/null

if [[ $? != "0" ]]; then
echo "error: generating code coverage requires jscoverage"
echo "error: it can be downloaded from https://github.com/visionmedia/node-jscoverage"
exit 1
fi

rm -rf lib-cov
jscoverage lib lib-cov
SPNPM_COV=1 REPORTER="html-cov" node test/test.js > coverage.html
SPNPM_COV=1 REPORTER="json-cov" node test/test.js > coverage.json
62 changes: 62 additions & 0 deletions scripts/results.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env node

var results = require('../coverage.json')
, util = require('util')

var colors = {}
colors.cyan = function(s) {
return util.format('\033[96m%s\033', s)
}

colors.red = function(s) {
return util.format('\033[31m%s\033[0m', s)
}

colors.grey = function(s) {
return util.format('\033[90m%s\033[0m', s)
}

colors.yellow = function(s) {
return util.format('\033[93m%s\033[0m', s)
}

colors.magenta = function(s) {
return util.format('\033%s\033[0m', s)
}

var sloc = results.sloc
, hits = results.hits
, coverage = results.coverage
, files = results.files

console.log()
console.log('Code Coverage:')
console.log()
console.log(colors.magenta(' Overall'))
console.log(' COVERAGE:', formatCoverage(coverage))
console.log(' SLOC: ', colors.cyan(sloc))
console.log(' HITS: ', colors.cyan(hits))

files.forEach(function(file) {
getFile(file)
})

function formatCoverage(cov) {
var c = +(cov).toFixed(2)+'%'
if (cov < 25) {
return colors.red(c)
} else if (cov < 50) {
return colors.yellow(c)
} else if (cov < 75) {
return colors.grey(c)
}
return colors.cyan(c)
}

function getFile(file) {
console.log()
console.log(colors.magenta(' '+file.filename))
console.log(' COVERAGE:', formatCoverage(file.coverage))
console.log(' SLOC: ', colors.cyan(file.sloc))
console.log(' HITS: ', colors.cyan(file.hits))
}
159 changes: 159 additions & 0 deletions test/fixtures/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
var util = require('util')

var privateRegistry = {}
, publicRegistry = {}
, publicRegistry2 = {}


privateRegistry.port = 8022
privateRegistry.host = 'http://localhost'
privateRegistry.url = [privateRegistry.host, privateRegistry.port].join(':')

publicRegistry.port = 8023
publicRegistry.host = 'http://localhost'
publicRegistry.url = [publicRegistry.host, publicRegistry.port].join(':')

publicRegistry2.port = 8024
publicRegistry2.host = 'http://localhost'
publicRegistry2.url = [publicRegistry2.host, publicRegistry2.port].join(':')

exports.private = privateRegistry
exports.public = publicRegistry
exports.public2 = publicRegistry2
exports.port = 8021
exports.host = 'http://localhost:'+exports.port

exports.portSSL = 8020

exports.json = function(res, code, body) {
res.writeHead(code, {
'Content-Type': 'application/json'
})
res.end(JSON.stringify(body))
}

exports.wrongStatusCode = function(rec, exp, done) {
var msg = util.format('Status Code: %d, but should have been %d',
rec, exp)
return done(new Error(msg))
}

exports.invalidRes = function(rec, done) {
var msg = util.format('Invalid response received: %j', rec)
return done(new Error(msg))
}

exports.url = function(url) {
return url.replace(/\/\//g, '/')
}

exports.publicOk = function(done) {
return function(err, res, body) {
if (err) return done(err)
if (res.statusCode !== 200) {
return exports.wrongStatusCode(res.statusCode, 200, done)
}
if (!body.server) {
return exports.invalidRes(res, done)
}
if (body.server !== 'public') {
var msg = 'Request should have been proxied to the public registry'
return done(new Error(msg))
}
done()
}
}

exports.privateOk = function(done) {
return function(err, res, body) {
if (err) return done(err)
if (res.statusCode !== 200) {
return exports.wrongStatusCode(res.statusCode, 200, done)
}
if (!body.server) {
return exports.invalidRes(res, done)
}
if (body.server !== 'private') {
var msg = 'Request should have been proxied to the private registry'
return done(new Error(msg))
}
done()
}
}

exports.publicNotFound = function(done) {
return function(err, res, body) {
if (err) return done(err)
if (res.statusCode !== 404) {
return exports.wrongStatusCode(res.statusCode, 404, done)
}
if (!body.server) {
return exports.invalidRes(res, done)
}
if (body.server !== 'public') {
var msg = 'Request should have been proxied to the public registry'
return done(new Error(msg))
}
done()
}
}

exports.privateNotFound = function(done) {
return function(err, res, body) {
if (err) return done(err)
if (res.statusCode !== 404) {
return exports.wrongStatusCode(res.statusCode, 404, done)
}
if (!body.server) {
return exports.invalidRes(res, done)
}
if (body.server !== 'private') {
var msg = 'Request should have been proxied to the private registry'
return done(new Error(msg))
}
done()
}
}

exports.error = function(done) {
return function(err, res, body) {
if (err) return done(err)
if (res.statusCode !== 400) {
return exports.wrongStatusCode(res.statusCode, 400, done)
}
done()
}
}

exports.list = {
get: [
'/-/jsonp/jsonp_blah'
, '/-/all/since'
, '/-/rss'
, '/-/rss/package_blah'
, '/-/all'
, '/-/all/-/jsonp/jsonp_blah'
, '/-/short'
, '/-/scripts'
, '/-/by-field'
, '/-/fields'
, '/-/needbuild'
, '/-/prebuilt'
, '/-/nonlocal'
, '/-/by-user/user_blah'
, '/-/starred-by-user/user_blah'
, '/-/starred-by-package/user_blah'
, '/-/_view/all'
, '/-/_list/all'
, '/-/_show/all'
, '/-/users'
, '/-/user/user_blah'
, '/_users/user_blah'
, '/-/user-by-email/user_blah'
],
put: [
'/-/user/user_blah'
, '/_users/user_blah'
, '/public_users/user_blah'
]
}
54 changes: 54 additions & 0 deletions test/fixtures/private.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
var http = require('http')
, url = require('url')
, common = require('./common')

exports.start = function(cb) {
exports.server = http.createServer(handle)
.on('error', cb)
.listen(common.private.port, cb)
}

exports.stop = function(cb) {
exports.server.on('close', cb)
exports.server.close()
}

function handle(req, res) {
var u = common.url(req.url)
switch (u) {
case '/priv-basic-ok':
case '/priv-wl-ok-get':
case '/priv-wl-ok-put':
case '/wl-ok-put-priv':
case '/_session':
case '/priv-basic-ok/0.0.1':
pkgOk(req, res)
break
case '/priv-basic-error':
pkgError(req, res)
break
case '/priv-basic-notfound':
default:
pkgNotFound(req, res)
break
}
}

function pkgOk(req, res) {
common.json(res, 200, {
server: 'private'
})
}

function pkgNotFound(req, res) {
common.json(res, 404, {
server: 'private',
message: 'not_found'
})
}

function pkgError(req, res) {
common.json(res, 400, {
server: 'private'
})
}
80 changes: 80 additions & 0 deletions test/fixtures/public.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
var http = require('http')
, url = require('url')
, common = require('./common')

exports.start = function(cb) {
exports.server = http.createServer(handle)
.on('error', cb)
.listen(common.public.port, cb)
}

exports.stop = function(cb) {
exports.server.on('close', cb)
exports.server.close()
}

function handle(req, res) {
var u = common.url(req.url)
switch (u) {
case '/pub-basic-ok':
case '/basic-ok':
case '/pub-wl-ok':
case '/wl-ok-put':
case '/':
case '/favicon.ico':
case '/-/jsonp/jsonp_blah':
case '/-/all/since':
case '/-/rss':
case '/-/rss/package_blah':
case '/-/all':
case '/-/all/-/jsonp/jsonp_blah':
case '/-/short':
case '/-/scripts':
case '/-/by-field':
case '/-/fields':
case '/-/needbuild':
case '/-/prebuilt':
case '/-/nonlocal':
case '/-/by-user/user_blah':
case '/-/starred-by-user/user_blah':
case '/-/starred-by-package/user_blah':
case '/-/_view/all':
case '/-/_list/all':
case '/-/_show/all':
case '/-/users':
case '/-/user/user_blah':
case '/_users/user_blah':
case '/-/user-by-email/user_blah':
case '/-/user/user_blah':
case '/_users/user_blah':
case '/public_users/user_blah':
pkgOk(req, res)
break
case '/pub-error':
pkgError(req, res)
break
case '/pub-basic-notfound':
default:
pkgNotFound(req, res)
break
}
}

function pkgOk(req, res) {
common.json(res, 200, {
server: 'public'
})
}

function pkgNotFound(req, res) {
common.json(res, 404, {
server: 'public',
message: 'not_found'
})
}

function pkgError(req, res) {
common.json(res, 400, {
server: 'public'
})
}
Loading

0 comments on commit e0cfa64

Please sign in to comment.