Skip to content

Commit

Permalink
Rewrite using natively supported ES6 features
Browse files Browse the repository at this point in the history
  • Loading branch information
amacneil committed Apr 27, 2016
1 parent 233fa37 commit c47caf1
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 71 deletions.
10 changes: 8 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
{
"extends": "airbnb-base",
"extends": "airbnb-base/legacy",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"env": {
"es6": true,
"mocha": true
},
"rules": {
"arrow-body-style": 0
"arrow-body-style": 0,
"new-cap": 0
}
}
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ language: node_js
node_js:
- "4"
- "5"
script: npm run prepublish
- "6"
92 changes: 49 additions & 43 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,63 @@
import fetch from 'node-fetch';
import http from 'http';
import debug from 'debug';
var debug = require('debug');
var http = require('http');
var nodeFetch = require('node-fetch');

const log = debug('fetch-test-server');
var log = debug('fetch-test-server');

export default class TestServer {
constructor(app) {
this.server = http.createServer(app);

['delete', 'get', 'head', 'options', 'patch', 'post', 'put'].forEach((method) => {
this[method] = (path, options) =>
this.fetch(path, Object.assign({}, options, { method: method.toUpperCase() }));
});
function TestServer(app) {
if (!(this instanceof TestServer)) {
return new TestServer;
}

listen() {
if (!this.listener) {
this.listener = new Promise((resolve, reject) => {
this.server.listen(0, () => resolve())
.on('error', (err) => reject(err));
});
}
this.server = http.createServer(app);

return this.listener;
}
['delete', 'get', 'head', 'options', 'patch', 'post', 'put'].forEach((method) => {
this[method] = (path, options) =>
this.fetch(path, Object.assign({}, options, { method: method.toUpperCase() }));
});

close() {
this.listener = null;
Object.defineProperty(this, 'address', {
get: function address() {
var port = this.server.address().port;
return `http://localhost:${port}`;
}
});
}

return new Promise((resolve, reject) => {
this.server.close((err) => (err ? reject(err) : resolve()));
TestServer.prototype.listen = function listen() {
if (!this.listener) {
this.listener = new Promise((resolve, reject) => {
this.server.listen(0, () => resolve())
.on('error', (err) => reject(err));
});
}

get address() {
const { port } = this.server.address();
return `http://localhost:${port}`;
}
return this.listener;
};

fetch(path, opts) {
return this.listen().then(() => {
const options = Object.assign({ headers: {} }, opts);
TestServer.prototype.close = function close() {
this.listener = null;

// automatic JSON encoding
if (typeof options.body === 'object') {
options.headers['Content-Type'] = 'application/json';
options.body = JSON.stringify(options.body);
}
return new Promise((resolve, reject) => {
this.server.close((err) => (err ? reject(err) : resolve()));
});
};

const url = `${this.address}${path}`;
log(url, options);
TestServer.prototype.fetch = function fetch(path, opts) {
return this.listen().then(() => {
var url = `${this.address}${path}`;
var options = Object.assign({ headers: {} }, opts);

return fetch(url, options);
});
}
}
// automatic JSON encoding
if (typeof options.body === 'object') {
options.headers['Content-Type'] = 'application/json';
options.body = JSON.stringify(options.body);
}

log(url, options);

return nodeFetch(url, options);
});
};

module.exports = TestServer;
33 changes: 19 additions & 14 deletions index.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { assert } from 'chai';
var assert = require('chai').assert;

import TestServer from './index';
var TestServer = require('.');

// very simple http handler
const app = (req, res) => {
const headers = {};
var app = (req, res) => {
var headers = {};
if (req.headers.ping) {
headers.pong = req.headers.ping;
}
Expand All @@ -14,7 +14,7 @@ const app = (req, res) => {
};

describe('TestServer', () => {
let server;
var server;

beforeEach(() => {
server = new TestServer(app);
Expand All @@ -24,11 +24,16 @@ describe('TestServer', () => {
assert.typeOf(server.server, 'object');
});

it('supports calling constructor', () => {
server = TestServer(app);
assert.typeOf(server.server, 'object');
});

it('listens on a random port', () => {
assert.isNull(server.server.address());

return server.listen().then(() => {
const address = server.server.address();
var address = server.server.address();

assert.isAbove(address.port, 10000);
});
Expand Down Expand Up @@ -75,8 +80,8 @@ describe('TestServer', () => {
});

it('supports fetch options', () => {
const opts = {
headers: { ping: 'foo' },
var opts = {
headers: { ping: 'foo' }
};

return server.fetch('/bar', opts).then((res) => {
Expand All @@ -85,14 +90,14 @@ describe('TestServer', () => {
});

it('supports helper methods', () => {
for (const method of ['delete', 'get', 'head', 'options', 'patch', 'post', 'put']) {
assert.typeOf(server[method], 'function');
}

const opts = {
headers: { ping: 'foo' },
var opts = {
headers: { ping: 'foo' }
};

['delete', 'get', 'head', 'options', 'patch', 'post', 'put'].forEach((method) => {
assert.typeOf(server[method], 'function');
});

return server.post('/mail', opts).then((res) => {
assert.strictEqual(res.status, 200);
assert.strictEqual(res.headers.get('pong'), 'foo');
Expand Down
14 changes: 3 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@
"name": "fetch-test-server",
"version": "1.0.0",
"description": "Test node.js HTTP servers using the fetch API",
"main": "dist/index.js",
"files": [
"dist"
],
"main": "index.js",
"scripts": {
"build": "babel index.js -d dist",
"clean": "rm -rf dist",
"lint": "eslint *.js",
"prepublish": "npm run clean && npm run lint && npm run test && npm run build",
"test": "mocha --compilers js:babel-register *.test.js"
"mocha": "mocha *.test.js",
"test": "npm run lint && npm run mocha"
},
"repository": {
"type": "git",
Expand All @@ -38,9 +33,6 @@
"node-fetch": "^1.5.1"
},
"devDependencies": {
"babel-cli": "6.7.7",
"babel-preset-es2015": "6.6.0",
"babel-register": "6.7.2",
"chai": "3.5.0",
"eslint": "2.8.0",
"eslint-config-airbnb-base": "1.0.4",
Expand Down

0 comments on commit c47caf1

Please sign in to comment.