Comparing version 0.0.2 to 0.1.1
112
lib/index.js
const http = require('http'); | ||
const assert = require('assert'); | ||
function assembleHeaders(method, headers, data){ | ||
headers = typeof headers == 'object' ? headers : {}; | ||
if(headers['--no-auto'] === true){ | ||
delete headers['--no-auto']; | ||
return headers; | ||
} | ||
headers.date = headers.date || (new Date()).toUTCString(); | ||
if(data.length > 0){ | ||
headers['Content-Type'] = headers['Content-Type'] || 'application/octet-stream'; | ||
headers['Content-Length'] = headers['Content-Length'] || Buffer.from(data).length; | ||
} | ||
return headers; | ||
} | ||
function request(url, headers, method, data){ | ||
data = typeof data == 'undefined' ? '' : String(data); | ||
return new Promise(function(resolve, reject){ | ||
@@ -12,3 +30,3 @@ url = new URL(url); | ||
path: url.pathname + url.search, | ||
headers: typeof headers == 'object' ? headers : {} | ||
headers: assembleHeaders(method, headers, data) | ||
}; | ||
@@ -27,4 +45,3 @@ let req = http.request(options, res => { | ||
req.on('error', reject); | ||
if(typeof data == 'string') | ||
req.write(data); | ||
req.write(data); | ||
req.end(); | ||
@@ -34,85 +51,8 @@ }); | ||
[ 'get', 'post', 'patch', 'put', 'delete', 'head', 'options' ].forEach( m => { | ||
module.exports[m] = (url, headersOrBody, body) => | ||
request(url, headersOrBody, m.toUpperCase(), body || headersOrBody); | ||
}); | ||
class Suite{ | ||
constructor(response){ | ||
this.response = response; | ||
} | ||
status(s){ | ||
let status = this.response.status; | ||
switch(typeof s){ | ||
case 'number': assert.deepEqual(s, status); break; | ||
} | ||
return this; | ||
} | ||
json(cb){ | ||
let body = JSON.parse(this.response.body); | ||
assert(cb(body)); | ||
return this; | ||
} | ||
} | ||
class Endpoint{ | ||
constructor(method, url){ | ||
this.method = method; | ||
this.url = url; | ||
} | ||
async query(params, headersOrBody, body){ | ||
let oldURL = this.url; | ||
this.url += '?' + params; | ||
let r = await this.reach(headersOrBody, body); | ||
this.url = oldURL; | ||
return r; | ||
} | ||
async reach(headersOrBody, body){ | ||
body = body || headersOrBody; | ||
let r = await request(this.url, headersOrBody, this.method, body); | ||
return new Suite(r); | ||
} | ||
} | ||
module.exports = { | ||
get(url, headers){ | ||
return request(url, headers || {}, 'GET', false); | ||
}, | ||
post(url, headersOrBody, body){ | ||
body = body || headersOrBody; | ||
return request(url, headersOrBody, 'POST', body); | ||
}, | ||
patch(url, headersOrBody, body){ | ||
body = body || headersOrBody; | ||
return request(url, headersOrBody, 'PATCH', body); | ||
}, | ||
delete(url, headers){ | ||
return request(url, headers, 'DELETE', false); | ||
}, | ||
put(url, headersOrBody, body){ | ||
body = body || headersOrBody; | ||
return request(url, headersOrBody, 'PUT', body); | ||
}, | ||
head(url, headers){ | ||
return request(url, headers || {}, 'HEAD', false); | ||
}, | ||
options(url, headers){ | ||
return request(url, headers || {}, 'OPTIONS', false); | ||
}, | ||
request: request, | ||
Endpoint: Endpoint | ||
}; | ||
module.exports.request = request; | ||
module.exports.del = module.exports.delete; |
{ | ||
"name": "muhb", | ||
"version": "0.0.2", | ||
"description": "A simple set of functions for coding easy to read HTTP requests.", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"test": "mocha -b --no-diff test/spec.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://gitlab.com/GCSBOSS/muhb.git" | ||
}, | ||
"keywords": [ | ||
"http", | ||
"request", | ||
"simple" | ||
], | ||
"author": "gcsboss", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://gitlab.com/GCSBOSS/muhb/issues" | ||
}, | ||
"homepage": "https://gitlab.com/GCSBOSS/muhb#readme" | ||
"name": "muhb", | ||
"version": "0.1.1", | ||
"description": "A simple set of functions for coding easy to read HTTP requests.", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"test": "mocha -b --no-diff test/*.js", | ||
"coverage": "nyc -r html -r text-summary mocha -b --no-diff test/*.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://gitlab.com/GCSBOSS/muhb.git" | ||
}, | ||
"keywords": [ | ||
"http", | ||
"request", | ||
"simple", | ||
"api", | ||
"test", | ||
"easy", | ||
"rest" | ||
], | ||
"author": "Guilherme C. Souza", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://gitlab.com/GCSBOSS/muhb/issues" | ||
}, | ||
"homepage": "https://gitlab.com/GCSBOSS/muhb#readme" | ||
} |
# MUHB | ||
Muhb is a simple library for writing easy to read HTTP requet code. | ||
**M**ethod, **U**RL, **H**eaders and **B**ody | ||
It is recommended for writing test cases, and other unofficial purposes. | ||
- Is a simple library for writing easy to read HTTP requet code. | ||
- It is recommended for writing test cases, and other "unofficial" purposes. | ||
- Run over promises. | ||
Muhb run over promises. | ||
> Obs.: Do not use it in production YET. | ||
> Obs.: Do not use it in production. | ||
## Method Signatures | ||
- GET, DELETE, HEAD and OPTIONS: `method ( String url [, Object headers] )` | ||
- POST, PUT and PATCH: `method ( String url [, Object headers] [, String body] )` | ||
MUHB exposes the same signature for all available methods: | ||
`method ( String url [, Object headers] [, String body] )` | ||
## Usage | ||
Install with: `npm i muhb`. | ||
Getting NodeJS homepage: | ||
@@ -39,5 +42,22 @@ | ||
var { status, headers, body } = await put('https://nodejs.org/en/', { myHeader: 'example' }, 'key=value&key=value'); | ||
var { status, headers, body } = await put( | ||
'https://nodejs.org/en/', | ||
{ myHeader: 'example' }, | ||
'key=value&key=value' | ||
); | ||
``` | ||
If you would like MUHB to not generate automatic content and date headers, send | ||
a ghost parameter like this: | ||
```js | ||
const { put } = require('muhb'); | ||
var { status, headers, body } = await put( | ||
'https://nodejs.org/en/', | ||
{ '--no-auto': true, myHeader: 'example' }, | ||
'key=value&key=value' | ||
); | ||
``` | ||
Having all available muhb methods: | ||
@@ -58,2 +78,3 @@ | ||
## Contributing | ||
We will be delighted to receive your [issues](https://gitlab.com/GCSBOSS/muhb/issues/new) and [MRs](https://gitlab.com/GCSBOSS/muhb/merge_requests/new). | ||
We will be delighted to receive your [issues](https://gitlab.com/GCSBOSS/muhb/issues/new) | ||
and [MRs](https://gitlab.com/GCSBOSS/muhb/merge_requests/new). |
106
test/spec.js
@@ -5,91 +5,101 @@ const assert = require('assert'); | ||
describe('::get(url[, headers])', function(){ | ||
describe('Verbs', function(){ | ||
it('should properly reach a GET endpoint', async function(){ | ||
let r = await muhb.get(HTTPBIN_URL + '/get'); | ||
assert.equal(r.status, 200); | ||
assert.equal(typeof r.headers, 'object'); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers, 'object'); | ||
let o = JSON.parse(r.body); | ||
assert.equal(typeof o.args, 'object'); | ||
assert.strictEqual(typeof o.args, 'object'); | ||
}); | ||
}); | ||
describe('::head(url[, headers])', function(){ | ||
it('should properly reach a GET endpoint', async function(){ | ||
let r = await muhb.head(HTTPBIN_URL + '/get'); | ||
assert.equal(r.status, 200); | ||
assert.equal(typeof r.headers, 'object'); | ||
assert.equal(r.body, ''); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers, 'object'); | ||
assert.strictEqual(r.body, ''); | ||
}); | ||
}); | ||
describe('::post(url[, headers][, body])', function(){ | ||
it('should properly reach a POST endpoint', async function(){ | ||
let r = await muhb.post(HTTPBIN_URL + '/post', 'balela'); | ||
assert.equal(r.status, 200); | ||
assert.equal(typeof r.headers, 'object'); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers, 'object'); | ||
let o = JSON.parse(r.body); | ||
assert.equal(o.data, 'balela'); | ||
assert.strictEqual(o.data, 'balela'); | ||
r = await muhb.post(HTTPBIN_URL + '/post', {'thak-thek': 'that'}); | ||
o = JSON.parse(r.body); | ||
assert.equal(o.headers['Thak-Thek'], 'that'); | ||
assert.strictEqual(o.headers['Thak-Thek'], 'that'); | ||
}); | ||
}); | ||
describe('::put(url[, headers][, body])', function(){ | ||
it('should properly reach a PUT endpoint', async function(){ | ||
let r = await muhb.put(HTTPBIN_URL + '/put', 'balela'); | ||
assert.equal(r.status, 200); | ||
assert.equal(typeof r.headers, 'object'); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers, 'object'); | ||
let o = JSON.parse(r.body); | ||
assert.equal(o.data, 'balela'); | ||
assert.strictEqual(o.data, 'balela'); | ||
r = await muhb.put(HTTPBIN_URL + '/put', {'thak-thek': 'that'}); | ||
o = JSON.parse(r.body); | ||
assert.equal(o.headers['Thak-Thek'], 'that'); | ||
assert.strictEqual(o.headers['Thak-Thek'], 'that'); | ||
}); | ||
}); | ||
describe('::patch(url[, headers][, body])', function(){ | ||
it('should properly reach a PATCH endpoint', async function(){ | ||
let r = await muhb.patch(HTTPBIN_URL + '/patch', 'balela'); | ||
assert.equal(r.status, 200); | ||
assert.equal(typeof r.headers, 'object'); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers, 'object'); | ||
let o = JSON.parse(r.body); | ||
assert.equal(o.data, 'balela'); | ||
assert.strictEqual(o.data, 'balela'); | ||
r = await muhb.patch(HTTPBIN_URL + '/patch', {'thak-thek': 'that'}); | ||
o = JSON.parse(r.body); | ||
assert.equal(o.headers['Thak-Thek'], 'that'); | ||
assert.strictEqual(o.headers['Thak-Thek'], 'that'); | ||
}); | ||
}); | ||
describe('::delete(url[, headers])', function(){ | ||
it('should properly reach a DELETE endpoint', async function(){ | ||
let r = await muhb.delete(HTTPBIN_URL + '/delete'); | ||
assert.equal(r.status, 200); | ||
assert.equal(typeof r.headers, 'object'); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers, 'object'); | ||
let o = JSON.parse(r.body); | ||
assert.equal(typeof o.args, 'object'); | ||
assert.strictEqual(typeof o.args, 'object'); | ||
}); | ||
it('should properly reach a GET endpoint', async function(){ | ||
let r = await muhb.options(HTTPBIN_URL + '/get'); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers.allow, 'string'); | ||
assert.strictEqual(r.body, ''); | ||
}); | ||
}); | ||
describe('::options(url[, headers])', function(){ | ||
describe('Automatic Headers', function(){ | ||
it('should properly reach a GET endpoint', async function(){ | ||
let r = await muhb.options(HTTPBIN_URL + '/get'); | ||
assert.equal(r.status, 200); | ||
assert.equal(typeof r.headers.allow, 'string'); | ||
assert.equal(r.body, ''); | ||
it('should generate automatic headers', async function(){ | ||
let { body } = await muhb.post(HTTPBIN_URL + '/post'); | ||
let o = JSON.parse(body); | ||
assert(o.headers.Date); | ||
assert(!o.headers['Content-Type']); | ||
assert(!o.headers['Content-Length']); | ||
}); | ||
it('should generate content length and type headers when body is present', async function(){ | ||
let { body } = await muhb.post(HTTPBIN_URL + '/post', 'haha'); | ||
let o = JSON.parse(body); | ||
assert(o.headers.Date); | ||
assert.strictEqual(o.headers['Content-Type'], 'application/octet-stream'); | ||
assert.strictEqual(o.headers['Content-Length'], '4'); | ||
}); | ||
it('should priorize user headers', async function(){ | ||
let { body } = await muhb.post(HTTPBIN_URL + '/post', {'Content-Type': 'text/plain'}, 'haha'); | ||
let o = JSON.parse(body); | ||
assert.strictEqual(o.headers['Content-Type'], 'text/plain'); | ||
}); | ||
it('should not generate automatic headers when specified', async function(){ | ||
let { body } = await muhb.post(HTTPBIN_URL + '/post', {'--no-auto': true}, 'haha'); | ||
let o = JSON.parse(body); | ||
assert(!o.headers.Date); | ||
assert(!o.headers['Content-Type']); | ||
assert(!o.headers['Content-Length']); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
12793
10
79
137