Comparing version 0.1.1 to 1.0.0
@@ -0,3 +1,6 @@ | ||
const assert = require('assert'); | ||
const http = require('http'); | ||
const getAssertions = require('./assertions'); | ||
function assembleHeaders(method, headers, data){ | ||
@@ -21,2 +24,28 @@ headers = typeof headers == 'object' ? headers : {}; | ||
function applyMethods(context, root){ | ||
root = root || ''; | ||
[ 'get', 'post', 'patch', 'put', 'delete', 'head', 'options' ].forEach( m => { | ||
context[m] = (url, headersOrBody, body) => | ||
request(root + url, headersOrBody, m.toUpperCase(), body || headersOrBody); | ||
}); | ||
} | ||
function root(url){ | ||
assert.strictEqual(typeof url, 'string'); | ||
let context = {}; | ||
applyMethods(context, url); | ||
return context; | ||
} | ||
function onResponse(res, body, cb){ | ||
let r = { | ||
status: res.statusCode, | ||
headers: res.headers, | ||
body: body | ||
} | ||
r.assert = getAssertions(r); | ||
cb(r); | ||
} | ||
function request(url, headers, method, data){ | ||
@@ -38,7 +67,3 @@ data = typeof data == 'undefined' ? '' : String(data); | ||
res.on('data', chunk => body += chunk); | ||
res.on('end', () => resolve({ | ||
status: res.statusCode, | ||
headers: res.headers, | ||
body: body | ||
})); | ||
res.on('end', () => onResponse(res, body, resolve)); | ||
}); | ||
@@ -51,8 +76,7 @@ req.on('error', reject); | ||
[ 'get', 'post', 'patch', 'put', 'delete', 'head', 'options' ].forEach( m => { | ||
module.exports[m] = (url, headersOrBody, body) => | ||
request(url, headersOrBody, m.toUpperCase(), body || headersOrBody); | ||
}); | ||
applyMethods(module.exports); | ||
module.exports.request = request; | ||
module.exports.del = module.exports.delete; | ||
module.exports.root = root; |
{ | ||
"name": "muhb", | ||
"version": "0.1.1", | ||
"version": "1.0.0", | ||
"description": "A simple set of functions for coding easy to read HTTP requests.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -9,4 +9,2 @@ # MUHB | ||
> Obs.: Do not use it in production YET. | ||
## Method Signatures | ||
@@ -77,4 +75,45 @@ | ||
Testing response data: | ||
```js | ||
var { assert } = await get('https://example.com'); | ||
// Assert about your reposnse body. | ||
assert.body.exactly('foobar'); | ||
assert.body.contains('oba'); | ||
assert.body.match(/oo.a/); | ||
// Mostly chainable. | ||
assert.body.type('application/json').length(23); | ||
// Test JSON bodies. | ||
assert.body.json | ||
.hasKey('foo') | ||
.match('foo', 'bar') | ||
.empty(); // test for {} | ||
// Test JSON array. | ||
assert.body.json.array | ||
.match(1, 'bar') | ||
.includes('foo') | ||
.empty(); | ||
// Assert about response status code | ||
assert.status.is(200); | ||
assert.status.not(400); | ||
assert.status.in([ 200, 203, 404 ]); | ||
assert.status.notIn([ 500, 403, 201 ]); | ||
assert.status.type(2); // Test for 2xx | ||
assert.status.notType(5) // Test for NOT 5xx | ||
// Assert about response headers | ||
assert.headers | ||
.has('authorization') | ||
.match('connection', 'close'); | ||
``` | ||
## 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). |
114
test/spec.js
const assert = require('assert'); | ||
const muhb = require('../lib/index.js'); | ||
const HTTPBIN_URL = process.env.HTTPBIN_URL || 'http://localhost'; | ||
const HTTPBIN_URL = process.env.HTTPBIN_URL || 'http://localhost/'; | ||
@@ -105,1 +105,113 @@ describe('Verbs', function(){ | ||
}); | ||
describe('Root Definition', function(){ | ||
it('should properly reach a rooted GET endpoint', async function(){ | ||
let base = muhb.root(HTTPBIN_URL); | ||
assert('post' in base); | ||
assert('get' in base); | ||
let r = await base.get('/get'); | ||
assert.strictEqual(r.status, 200); | ||
assert.strictEqual(typeof r.headers, 'object'); | ||
let o = JSON.parse(r.body); | ||
assert.strictEqual(typeof o.args, 'object'); | ||
}); | ||
}); | ||
describe('Assertions', function(){ | ||
var ep = muhb.root(HTTPBIN_URL); | ||
it('should be ok asserting truths over http status code', async function(){ | ||
let { assert: ass } = await ep.get('/get'); | ||
assert.doesNotThrow( () => ass.status.is(200) ); | ||
assert.doesNotThrow( () => ass.status.in([200, 201]) ); | ||
assert.doesNotThrow( () => ass.status.not(201) ); | ||
assert.doesNotThrow( () => ass.status.notIn([202, 201]) ); | ||
assert.doesNotThrow( () => ass.status.type(2) ); | ||
assert.doesNotThrow( () => ass.status.notType(3) ); | ||
}); | ||
it('should throw asserting falsehoods over http status code', async function(){ | ||
let { assert: ass } = await ep.get('/get'); | ||
assert.throws( () => ass.status.is(201) ); | ||
assert.throws( () => ass.status.in([202, 201]) ); | ||
assert.throws( () => ass.status.not(200) ); | ||
assert.throws( () => ass.status.notIn([200, 201]) ); | ||
assert.throws( () => ass.status.type(3) ); | ||
assert.throws( () => ass.status.notType(2) ); | ||
}); | ||
it('should be ok asserting truths over http headers', async function(){ | ||
let { assert: ass } = await ep.get('/get'); | ||
assert.doesNotThrow( () => ass.headers.has('content-length').has('date') ); | ||
assert.doesNotThrow( () => ass.headers.match('content-type', 'application/json') ); | ||
}); | ||
it('should throw asserting falsehoods over http headers', async function(){ | ||
let { assert: ass } = await ep.get('/get'); | ||
assert.throws( () => ass.headers.has('x-none') ); | ||
assert.throws( () => ass.headers.match('content-type', 'text/html') ); | ||
}); | ||
it('should be ok asserting truths over response body', async function(){ | ||
let { assert: ass } = await ep.get('/user-agent'); | ||
assert.doesNotThrow( () => ass.body.exactly('{\n "user-agent": null\n}\n') ); | ||
assert.doesNotThrow( () => ass.body.contains('user-agent') ); | ||
assert.doesNotThrow( () => ass.body.match(/null/g) ); | ||
assert.doesNotThrow( () => ass.body.type('application/json') ); | ||
assert.doesNotThrow( () => ass.body.length(25) ); | ||
}); | ||
it('should throw asserting falsehoods over response body', async function(){ | ||
let { assert: ass } = await ep.get('/'); | ||
assert.throws( () => ass.body.exactly('barfoo') ); | ||
assert.throws( () => ass.body.contains('baz') ); | ||
assert.throws( () => ass.body.match(/bah/) ); | ||
assert.throws( () => ass.body.type('image/jpg') ); | ||
assert.throws( () => ass.body.length(1) ); | ||
assert.throws( () => ass.body.json ); | ||
}); | ||
it('should be ok asserting truths over json response body', async function(){ | ||
let { assert: ass } = await ep.get('/user-agent'); | ||
let assJSON = ass.body.json; | ||
assert.doesNotThrow( () => assJSON.hasKey('user-agent') ); | ||
assert.doesNotThrow( () => assJSON.match('user-agent', null) ); | ||
delete assJSON.object['user-agent']; | ||
assert.doesNotThrow( () => assJSON.empty() ); | ||
}); | ||
it('should throw asserting falsehoods over json response body', async function(){ | ||
let { assert: ass } = await ep.get('/user-agent'); | ||
let assJSON = ass.body.json; | ||
assert.throws( () => assJSON.hasKey('barfoo') ); | ||
assert.throws( () => assJSON.match('user-agent', 'bah') ); | ||
assert.throws( () => assJSON.empty(/bah/) ); | ||
assert.throws( () => assJSON.array ); | ||
}); | ||
it('should be ok asserting truths over json array response body', async function(){ | ||
let { assert: ass } = await ep.get('/user-agent'); | ||
let assJSON = ass.body.json; | ||
assJSON.object = [ 'foo', 'bar' ]; | ||
let assArr = assJSON.array; | ||
assert.doesNotThrow( () => assArr.match(1, 'bar') ); | ||
assert.doesNotThrow( () => assArr.includes('bar') ); | ||
assJSON.object = []; | ||
assert.doesNotThrow( () => assJSON.array.empty() ); | ||
}); | ||
it('should throw asserting falsehoods over json array response body', async function(){ | ||
let { assert: ass } = await ep.get('/user-agent'); | ||
let assJSON = ass.body.json; | ||
assJSON.object = [ 'bar', 'foo' ]; | ||
let assArr = assJSON.array; | ||
assert.throws( () => assArr.match(1, 'bar') ); | ||
assert.throws( () => assArr.includes('baz') ); | ||
assert.throws( () => assArr.empty() ); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
21893
11
326
0
118