erest
Version:
Easy to build api server depend on @leizm/web and express.
175 lines (174 loc) • 5.84 kB
JavaScript
"use strict";
/**
* @file API Agent
* @author Yourtion Guo <yourtion@gmail.com>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestAgent = void 0;
const node_assert_1 = require("node:assert");
const stream = require("node:stream");
const util = require("node:util");
const api_1 = require("./api");
const debug_1 = require("./debug");
const defaultFormatOutput = (data) => [null, data];
/** 返回对象结构字符串 */
function inspect(obj) {
return util.inspect(obj, { depth: 5, colors: true });
}
/**
* 测试代理类
*/
class TestAgent {
options;
key;
debug;
/**
* 构造函数
*
* @param method HTTP请求方法
* @param path 请求路径
* @param key 键名:`method path`
* @param sourceFile 源文件路径描述对象
* @param erestIns hojs实例
*/
constructor(method, path, key, sourceFile, erestIns) {
(0, node_assert_1.strict)(typeof method === "string", "`method` must be string");
(0, node_assert_1.strict)(api_1.SUPPORT_METHOD.indexOf(method.toLowerCase()) !== -1, `\`method\` must be one of ${api_1.SUPPORT_METHOD}`);
(0, node_assert_1.strict)(typeof path === "string", "`path` must be string");
(0, node_assert_1.strict)(path[0] === "/", '`path` must be start with "/"');
this.options = {
erest: erestIns,
sourceFile,
method: method.toLowerCase(),
path,
takeExample: false,
agentInput: {},
};
this.key = key;
this.debug = (0, debug_1.create)(`agent:${this.key}`);
this.debug("new: %s %s from %s", method, path, sourceFile.absolute);
}
/** 设置`supertest.Agent`实例 */
setAgent(agent) {
this.debug("setAgent");
this.options.agent = agent;
}
/** 初始化`supertest.Agent`实例 */
initAgent(app) {
const request = require("supertest");
(0, node_assert_1.strict)(request, "Install `supertest` first");
(0, node_assert_1.strict)(app, `express app instance could not be empty`);
(0, debug_1.test)("create supertest agent");
this.setAgent(request(app)[this.options.method](this.options.path));
}
/** 获取测试代理 */
agent() {
(0, debug_1.test)("agent");
return this;
}
/** 对测试结果加入文档 */
takeExample(name) {
this.debug("takeExample: %s", name);
this.options.agentTestName = name;
this.options.takeExample = true;
return this;
}
/** 设置请求header */
headers(data) {
this.debug("headers: %j", data);
this.options.agentHeader = data;
Object.keys(data).forEach((k) => this.options.agent?.set(k, data[k]));
return this;
}
/** 添加 query 参数 */
query(data) {
this.debug("query: %j", data);
Object.assign(this.options.agentInput, data);
this.options.agent?.query(data);
return this;
}
/** 添加输入参数 */
input(data) {
this.debug("input: %j", data);
Object.assign(this.options.agentInput, data);
if (this.options.method === "get" || this.options.method === "delete") {
this.options.agent?.query(data);
}
else {
this.options.agent?.send(data);
}
return this;
}
/** 添加 POST 参数 */
attach(data) {
this.debug("attach: %j", data);
for (const i in data) {
if (data[i] instanceof stream.Readable) {
this.options.agent?.attach(i, data[i]);
delete data[i];
}
else {
this.options.agent?.field(i, data[i]);
}
}
Object.assign(this.options.agentInput, data);
return this;
}
/** 保存输出结果到 Example */
saveExample() {
this.debug("Save Example: %o", this.options.takeExample);
if (this.options.takeExample) {
this.options.erest.api.$apis.get(this.key)?.example({
name: this.options.agentTestName,
path: this.options.agent.req.path,
headers: this.options.agentHeader,
input: this.options.agentInput || {},
output: this.options.agentOutput,
});
}
}
/** 获取输出结果 */
output(raw = false, save = false) {
const api = this.options.erest.api.$apis.get(this.key);
if (api) {
api.options.tested = true;
}
return this.options.agent?.then((res) => {
this.options.agentOutput = res.body;
if (raw)
return res;
const formatOutputReverse = this.options.erest.api.formatOutputReverse || defaultFormatOutput;
const [err2, ret] = formatOutputReverse(res.body);
if (err2)
throw err2;
if (save)
this.saveExample();
return ret;
});
}
/** 期望输出成功结果 */
success() {
this.debug("success");
return this.output(false, true)?.catch((err) => {
throw new Error(`${this.key} 期望API输出成功结果,但实际输出失败结果:${inspect(err)}`);
});
}
/** 期望输出失败结果 */
error() {
this.debug("error");
return this.output()
?.then((ret) => {
throw new Error(`${this.key} 期望API输出失败结果,但实际输出成功结果:${inspect(ret)}`);
})
.catch((err) => {
this.saveExample();
return err;
});
}
/** 获取原始输出 */
raw() {
this.debug("raw");
return this.output(true, true);
}
}
exports.TestAgent = TestAgent;