Skip to content

Commit

Permalink
Prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
fardog committed Aug 14, 2015
0 parents commit 5a8d1d3
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["standard"]
}
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

lib/
5 changes: 5 additions & 0 deletions bin/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node

var path = require('path')

require(path.join(process.cwd(), 'frockfile.js'))
31 changes: 31 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "frock",
"version": "0.0.0",
"description": "A configurable mock HTTP server",
"main": "lib/index.js",
"bin": {
"frock": "./bin/cli.js"
},
"scripts": {
"test": "npm run lint && npm run compile && babel test/index.js | tape",
"prepublish": "npm run compile",
"compile": "babel src --out-dir lib",
"lint": "standard src/**/*.js test/**/*.js"
},
"author": "Urban Airship",
"license": "Apache-2.0",
"devDependencies": {
"babel": "^5.6.14",
"eslint": "^1.1.0",
"eslint-config-standard": "^4.1.0",
"eslint-config-standard-react": "^1.0.4",
"eslint-plugin-react": "^3.2.2",
"eslint-plugin-standard": "^1.2.0",
"standard": "^5.1.0",
"tape": "^4.0.0"
},
"dependencies": {
"arrify": "^1.0.0",
"commuter": "^1.0.2"
}
}
112 changes: 112 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import http from 'http'

import commuter from 'commuter'
import arrayify from 'arrify'

export default createFrockInstance

function createFrockInstance (config = {}) {
const frock = {}
const handlers = new Map()
const servers = []

frock.run = run
frock.stop = stop
frock.reload = reload
frock.registerHandler = registerHandler

return frock

function run (ready = noop) {
let count = 0

config.servers.forEach(s => {
const router = commuter(defaultRoute, s.baseUrl)
const server = http.createServer(router)
const boundHandlers = []

s.routes.forEach(r => {
const methods = arrayify(r.methods).map(m => m.toLowerCase())

methods.forEach(m => {
const handler = handlers.get(r.handler)(
frock,
logger.bind(null, r.handler),
r.options
)

router[m](r.path, handler)
boundHandlers.push(handler)
})
})

servers.push({server, handlers: boundHandlers})
server.listen(s.port, done)
})

function done () {
++count

if (count >= config.servers.length) {
ready()
}
}
}

function registerHandler (name, handler) {
handlers.set(name, handler)
}

function reload (ready = noop) {
stop(() => run(ready))
}

function stop (ready = noop) {
servers.forEach(s => {
s.handlers.forEach(h => {
h.end(innerDone)
})

function innerDone (handler) {
const idx = s.handlers.indexOf(handler)

if (idx) {
s.handlers.splice(idx, 1)
} else {
throw new Error('No handler to remove, throwing to avoid infinite loop')
}

if (!s.handlers.length) {
s.server.close(() => done(s))
}
}
})

function done (server) {
const idx = servers.indexOf(server)

if (idx) {
servers.splice(idx, 1)
} else {
throw new Error('No server to remove, throwing to avoid infinite loop')
}

if (!servers.length) {
ready()
}
}
}
}

function defaultRoute (req, res) {
res.statusCode = 404
res.end('not found')
}

function logger (handler, level, msg, extra) {
console.log(`${handler}: [${level.toUpperCase()}] ${msg}`)
}

function noop () {
// nooperations
}

0 comments on commit 5a8d1d3

Please sign in to comment.