Skip to content

Instantly share code, notes, and snippets.

@fiddlerwoaroof
Created May 20, 2017 23:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fiddlerwoaroof/0148c450bdb6b7629eb9ce85a52619ff to your computer and use it in GitHub Desktop.
Save fiddlerwoaroof/0148c450bdb6b7629eb9ce85a52619ff to your computer and use it in GitHub Desktop.
Simple Tested Website in NodeJS
'use strict';
var http = require('http');
var url = require('url');
function OK(contentType, body, otherHeaders = {}) {
return [
200,
Object.assign({},
otherHeaders,
{'Content-Type': contentType}
),
body
];
}
function Dispatcher(requestUnpacker) {
if (! (this instanceof Dispatcher)) {
return new Dispatcher(...arguments);
} else {
// Do instance-specific stuff here...
this.requestUnpacker = requestUnpacker;
}
}
Dispatcher.prototype = {
dispatch(request) {
let [pathname, target] = this.requestUnpacker.unpack(request);
let result = 'No Result...';
switch (pathname) {
case '/hello':
result = `Hello, ${target}!`;
break;
case '/length':
result = `${target.length}`;
break;
}
return OK('text/plain', result);
}
}
function RequestUnpacker(defaultTarget='No One') {
if (! (this instanceof RequestUnpacker) ) {
return new RequestUnpacker(...arguments);
} else {
// Do instance-specific stuff here...
this.defaultTarget = defaultTarget;
}
}
RequestUnpacker.prototype = {
unpack(request) {
let {url:reqUrl} = request;
let {pathname, query:{target=this.defaultTarget}} = url.parse(reqUrl,true);
return [pathname,target];
}
}
function wiring() {
let requestUnpacker = RequestUnpacker();
let dispatcher = Dispatcher(requestUnpacker);
return (req,res) => {
let [status, headers, content] = dispatcher.dispatch(req);
res.writeHead(status, headers);
res.end(content);
}
}
(() => {
// given
let contentType = 'text/plain';
let body = 'the body';
let someHeaderValue = 'the value';
// when
let [actualStatus, {"Content-Type":actualContentType, someHeader}, actualBody] =
OK(contentType, body, {someHeader: someHeaderValue})
// then
console.log('OK returns expected values:')
console.log(' pathname:', actualStatus === 200 ? 'PASS' : `FAIL: actual was (${actualStatus})`);
console.log(' body:', actualBody === body ? 'PASS' : `FAIL: actual was (${actualBody})`);
console.log('content-type:', actualContentType === contentType ? 'PASS' : `FAIL: actual was (${actualContentType})`);
console.log(' someHeader:', someHeader === someHeaderValue ? 'PASS' : `FAIL: actual was (${someHeader})`);
console.log();
})();
(() => {
// given
let contentType = 'text/plain';
let body = 'the body';
let someHeaderValue = 'the value';
// when
let [actualStatus, {"Content-Type":actualContentType, someHeader}, actualBody] =
OK(contentType, body, {'Content-Type': 'application/foo', someHeader: someHeaderValue})
// then
console.log('OK contentType overrides other headers:')
console.log('content-type:', actualContentType === contentType ? 'PASS' : `FAIL: actual was (${actualContentType})`);
console.log(' someHeader:', someHeader === someHeaderValue ? 'PASS' : `FAIL: actual was (${someHeader})`);
console.log();
})();
(() => {
// given
let requestUnpacker = RequestUnpacker();
let request = {url: '/bob?target=baz'};
// when
let [pathname, target] = requestUnpacker.unpack(request)
// then
console.log('RequestUnpacker target passed test: ')
console.log(' pathname:', pathname === '/bob' ? 'PASS' : `FAIL: actual was (${pathname})`);
console.log(' body:', target === 'baz' ? 'PASS' : `FAIL: actual was (${target})`);
console.log();
})();
(() => {
// given
let defaultTarget = 'foo'
let requestUnpacker = RequestUnpacker('foo');
let request = {url: '/hello'};
// when
let [pathname, target] = requestUnpacker.unpack(request)
// then
console.log('RequestUnpacker default target test: ')
console.log(' pathname:', pathname === '/hello' ? 'PASS' : `FAIL: actual was (${pathname})`);
console.log(' body:', target === defaultTarget ? 'PASS' : `FAIL: actual was (${target})`);
console.log();
})();
(() => {
// given
let dispatcher = Dispatcher({ unpack(req) { return ['/hello', 'foo'] }});
// when
let [status, headers, actual] = dispatcher.dispatch(null);
// then
console.log('Hello Route test: ')
console.log(' status:', status === 200 ? 'PASS' : `FAIL: actual was (${status})`);
console.log(' headers:', headers['Content-Type'] === 'text/plain' ? 'PASS' : `FAIL: actual was (${headers['Content-Type']})`);
console.log(' body:', actual === 'Hello, foo!' ? 'PASS' : `FAIL: actual was (${actual})`);
console.log();
})();
(() => {
// given
let dispatcher = Dispatcher({ unpack(req) { return ['/length', 'foo'] }});
// when
let [status, headers, actual] = dispatcher.dispatch(null);
// then
console.log('Length Route test: ')
console.log(' status:', status === 200 ? 'PASS' : `FAIL: actual was (${status})`);
console.log(' headers:', headers['Content-Type'] === 'text/plain' ? 'PASS' : `FAIL: actual was (${headers['Content-Type']})`);
console.log(' body:', actual === '3' ? 'PASS' : `FAIL: actual was (${actual})`);
console.log();
})();
console.log('Starting server . . .');
http.createServer(wiring()).listen(9405);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment