'use strict'; const assert = require('assert'); const request = require('request'); const sym = Symbol('smart_request_data'); function smart_request(options) { let self = {}; self[sym] = {}; self[sym].error = Error(); Error.captureStackTrace(self[sym].error, smart_request); let result = new Promise(function(resolve, reject) { self[sym].request = request(options, function(err, res, body) { if (err) return reject(err); self[sym].response = res; resolve(body); }); }); return extend(self, result); } function extend(self, promise) { promise[sym] = self[sym]; Object.setPrototypeOf(promise, extensions); return promise; } var extensions = Object.create(Promise.prototype); extensions.status = function(expected) { let self_data = this[sym]; return extend(this, this.then(function(body) { try { assert.equal(self_data.response.statusCode, expected); } catch(err) { self_data.error.message = err.message; throw self_data.error; } return body; })); }; extensions.body_ok = function(expected) { let self_data = this[sym]; return extend(this, this.then(function(body) { try { if (Object.prototype.toString.call(expected) === '[object RegExp]') { assert(body.ok.match(expected), '\'' + body.ok + '\' doesn\'t match ' + expected); } else { assert.equal(body.ok, expected); } assert.equal(body.error, null); } catch(err) { self_data.error.message = err.message; throw self_data.error; } return body; })); }; extensions.body_error = function(expected) { let self_data = this[sym]; return extend(this, this.then(function(body) { try { if (Object.prototype.toString.call(expected) === '[object RegExp]') { assert(body.error.match(expected), body.error + ' doesn\'t match ' + expected); } else { assert.equal(body.error, expected); } assert.equal(body.ok, null); } catch(err) { self_data.error.message = err.message; throw self_data.error; } return body; })); }; extensions.request = function(cb) { cb(this[sym].request); return this; }; extensions.response = function(cb) { let self_data = this[sym]; return extend(this, this.then(function(body) { cb(self_data.response); return body; })); }; extensions.send = function(data) { this[sym].request.end(data); return this; }; module.exports = smart_request;