Skip to content

Commit 9dbbb84

Browse files
committed
Java:MultiDataSource 中 APIAuto 新增支持配置响应 JSON 的自定义断言规则,类似请求参数注入的写法,减少写脚本需求
1 parent 34afbcd commit 9dbbb84

3 files changed

Lines changed: 76 additions & 34 deletions

File tree

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@
436436
<div class="left-bar" style="border-top: #DDD 1px solid; position: relative">
437437
<input v-show="isRandomListShow != true && isRandomSubListShow != true" id="vTestRandomCount" v-model="testRandomCount" style="margin-left: 10px; min-width: 12px; max-width: 30px; width: auto; text-align: center" type="number" />
438438
<a v-show="isRandomListShow != true && isRandomSubListShow != true" style="margin-left: 4px;"></a>
439+
<a href="javascript:void(0)" @click="isEditReqLink = true" :style="{'color': isEditReqLink ? 'red' : 'gray'}" style="font-size: medium; padding-left: 10px">请求</a><a >|</a><a href="javascript:void(0)" @click="isEditReqLink = false" :style="{'color': isEditReqLink ? 'gray' : 'red'}" style="font-size: medium">响应</a>
439440
<a style="display: flex;flex-grow: 1;padding-left: 10px;padding-right: 2px;font-size: medium;color: black" >{{ (isRandomListShow || StringUtil.isEmpty(randomTestTitle, true) ? '参数注入 Random Test' : randomTestTitle) + (isRandomListShow || isRandomSubListShow ? ' (' + ((isRandomListShow ? randoms : randomSubs) || []).length + ')' : '') }}
440441
<a v-show="isRandomListShow != true && (currentRemoteItem || {}).Document != null" style="padding-right: 6px;padding-top: 2px" href="javascript:void(0)" @click="showRandomList(true, (currentRemoteItem || {}).Document)">
441442
父项列表

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/js/main.js

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,7 @@ https://github.com/Tencent/APIJSON/issues
12811281
requestCount: 1,
12821282
urlComment: '一对多关联查询。可粘贴浏览器/抓包工具/接口工具 的 Network/Header/Content 等请求信息,自动填充到界面,格式为 key: value',
12831283
selectIndex: 0,
1284+
isEditReqLink: false,
12841285
options: [], // [{name:"id", type: "integer", comment:"主键"}, {name:"name", type: "string", comment:"用户名称"}],
12851286
historys: [],
12861287
history: {name: '请求0'},
@@ -3304,6 +3305,7 @@ https://github.com/Tencent/APIJSON/issues
33043305
commentObj = JSONResponse.updateStandard({}, mapReq2);
33053306
}
33063307

3308+
const isRes = ! this.isEditReqLink
33073309
var isChainShow = this.isChainShow
33083310
var paths = (isChainShow ? this.chainPaths : this.casePaths) || []
33093311
var index = paths.length - 1
@@ -3353,6 +3355,7 @@ https://github.com/Tencent/APIJSON/issues
33533355
const req = isExportRandom && btnIndex <= 0 ? {
33543356
format: false,
33553357
'Random': {
3358+
isRes: isRes,
33563359
userId: userId,
33573360
toId: 0,
33583361
chainGroupId: cgId,
@@ -10574,12 +10577,13 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1057410577
}
1057510578
summaryItem.totalCount = allCount
1057610579

10580+
const isRes = ! this.isEditReqLink
1057710581
var methods = this.methods
1057810582
var method = this.isShowMethod() ? this.method : null
1057910583
var type = this.type
10580-
var json = this.getRequest(vInput.value, {})
10584+
var json = this.getRequest(isRes ? this.jsoncon : vInput.value, {})
1058110585
var url = this.getUrl()
10582-
var header = this.getHeader(vHeader.value)
10586+
var header = (isRes ? (this.currentHttpResponse || {}).headers : this.getHeader(vHeader.value)) || {}
1058310587

1058410588
ORDER_MAP = {} //重置
1058510589

@@ -10752,7 +10756,7 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1075210756
}
1075310757

1075410758
},
10755-
preScript
10759+
preScript, null, random.isRes
1075610760
);
1075710761
}
1075810762
catch (e) {
@@ -10942,9 +10946,12 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1094210946
totalCount: count
1094310947
}
1094410948

10949+
const isRes = ! this.isEditReqLink
1094510950
this.testRandomSingle(show, false, this.isRandomSubListShow, this.currentRandomItem,
1094610951
this.isShowMethod() ? this.method : null, this.type, this.getUrl()
10947-
, this.getRequest(vInput.value, {}), this.getHeader(vHeader.value), false, false, callback
10952+
, this.getRequest(isRes ? this.jsoncon : vInput.value, {})
10953+
, (isRes ? (this.currentHttpResponse || {}).headers : this.getHeader(vHeader.value)) || {}
10954+
, false, false, callback
1094810955
)
1094910956
}
1095010957
catch (e) {
@@ -10973,13 +10980,14 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1097310980
* @param show
1097410981
* @param callback
1097510982
*/
10976-
parseRandom: function (json, head, config, randomId, generateJSON, generateConfig, generateName, callback, preScript, ctx) {
10983+
parseRandom: function (json, head, config, randomId, generateJSON, generateConfig, generateName, callback, preScript, ctx, isRes) {
1097710984
var lines = config == null ? null : StringUtil.trim(config).split('\n')
1097810985
if (lines == null || lines.length <= 0) {
1097910986
// return null;
1098010987
callback('', '', json, head);
1098110988
return
1098210989
}
10990+
const isUI = this.isRandomSubListShow
1098310991
json = json || {};
1098410992
head = head || {};
1098510993

@@ -11103,12 +11111,14 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1110311111
}
1110411112
// alert('< current = ' + JSON.stringify(current, null, ' '))
1110511113

11106-
// FIXME 还需要吗?之前的替换字段功能都废弃了,这个导致顺序变化
11107-
if (key != lastKeyInPath || current.hasOwnProperty(key) == false) {
11108-
delete current[lastKeyInPath];
11114+
if (isRes) {
11115+
var real = current[key]
11116+
if (real !== val) {
11117+
throw new Error(p_k + ' != ' + (val == null ? 'null' : StringUtil.limitLength(StringUtil.get(val), 20)) + '!')
11118+
}
11119+
} else {
11120+
current[key] = val;
1110911121
}
11110-
11111-
current[key] = val;
1111211122
}
1111311123

1111411124
}
@@ -11327,29 +11337,43 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1132711337
var as1 = as[1] // default value
1132811338
var as2 = as[2] // GET /users
1132911339
var as3 = as[3] // account@host/index
11330-
var accountHostIndexPath = StringUtil.isEmpty(as3) ? '/' : as3 + (as3.indexOf('/') < 0 ? '/' : '')
1133111340
var isChain = StringUtil.isNotEmpty(as2)
11332-
var chainArr = isChain ? '(((ctx || {}).ctx || {}).map || {})[' + as2 + ']' : null; // [GET /users] = { account@host: [] }
11341+
var chainArr = isChain ? '(((ctx || {}).ctx || {}).map || {})[' + as2 + ']' : null; // [GET /users] = { account@host: [], account: [], host: [] }
1133311342
if (isChain) {
1133411343
as2 = parseJSON(as2, as2, true)
11344+
as3 = parseJSON(as3, as3, true)
1133511345
as.splice(2, 2)
1133611346
}
11347+
var as3s = isChain ? StringUtil.trim(as3) : ''
11348+
var accountHostIndexPath = isChain ? (StringUtil.isNumber(as3) ? '/' + as3 : (StringUtil.isEmpty(as3) ? '/' : as3s + (as3s.indexOf('/') < 0 ? '/' : ''))) : ''
1133711349

11338-
if (fun == PRE_REQ) {
11339-
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/req")' : '((ctx || {}).pre || {}).req'
11350+
if (fun == PRE_DATA) {
11351+
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/data", undefined, null, true)' : '((ctx || {}).pre || {}).data'
11352+
toEval = 'get4Path(' + source + ', ' + (value == 'PRE_DATA()' ? JSON.stringify(path) : '') + (isChain ? as.join(', ') + value.substring(end) : value.substring(start + 1));
11353+
}
11354+
else if (fun == PRE_REQ) {
11355+
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/req", undefined, null, true)' : '((ctx || {}).pre || {}).req'
1134011356
toEval = 'get4Path(' + source + ', ' + (value == 'PRE_REQ()' ? JSON.stringify(path) : '') + (isChain ? as.join(', ') + value.substring(end) : value.substring(start + 1));
1134111357
}
1134211358
else if (fun == PRE_ARG) {
11343-
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/arg")' : '((ctx || {}).pre || {}).arg'
11359+
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/arg", undefined, null, true)' : '((ctx || {}).pre || {}).arg'
1134411360
toEval = 'get4Path(' + source + ', ' + (value == 'PRE_ARG()' ? JSON.stringify(path) : '') + (isChain ? as.join(', ') + value.substring(end) : value.substring(start + 1));
1134511361
}
1134611362
else if (fun == PRE_RES) {
11347-
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/res")' : '((ctx || {}).pre || {}).res'
11363+
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/res", undefined, null, true)' : '((ctx || {}).pre || {}).res'
1134811364
toEval = 'get4Path(' + source + ', ' + (value == 'PRE_RES()' ? JSON.stringify(path) : '') + (isChain ? as.join(', ') + value.substring(end) : value.substring(start + 1));
1134911365
}
11350-
else if (fun == PRE_DATA) {
11351-
var source = isChain ? 'get4Path(' + chainArr + ', "' + accountHostIndexPath + '/data")' : '((ctx || {}).pre || {}).data'
11352-
toEval = 'get4Path(' + source + ', ' + (value == 'PRE_DATA()' ? JSON.stringify(path) : '') + (isChain ? as.join(', ') + value.substring(end) : value.substring(start + 1));
11366+
else if (fun == CUR_REQ) {
11367+
toEval = 'get4Path(((ctx || {}).cur || {}).req, ' + (value == 'CUR_REQ()' ? JSON.stringify(path) : '') + value.substring(start + 1);
11368+
}
11369+
else if (fun == CUR_ARG) {
11370+
toEval = 'get4Path(((ctx || {}).cur || {}).arg, ' + (value == 'CUR_ARG()' ? JSON.stringify(path) : '') + value.substring(start + 1);
11371+
}
11372+
else if (fun == CUR_RES) {
11373+
toEval = 'get4Path(((ctx || {}).cur || {}).res, ' + (value == 'CUR_RES()' ? JSON.stringify(path) : '') + value.substring(start + 1);
11374+
}
11375+
else if (fun == CUR_DATA) {
11376+
toEval = 'get4Path(((ctx || {}).cur || {}).data, ' + (value == 'CUR_DATA()' ? JSON.stringify(path) : '') + value.substring(start + 1);
1135311377
}
1135411378
else if (fun == CTX_GET) {
1135511379
toEval = 'get4Path((ctx || {}).ctx, ' + (value == 'CTX_GET()' ? JSON.stringify(path) : '') + value.substring(start + 1);
@@ -11381,9 +11405,6 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1138111405
else if (as1 == 'CUR_RES') {
1138211406
as[1] = '((ctx || {}).cur || {}).res'
1138311407
}
11384-
else if (as1 == 'MAP') {
11385-
as[1] = '((ctx || {}).map || {})'
11386-
}
1138711408

1138811409
if (as.length >= 1) {
1138911410
as[0] = 'get4Path(' + as[1] + ', ' + StringUtil.trim(as[0]) + ')'
@@ -11531,7 +11552,7 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1153111552
}
1153211553

1153311554
this.coverage = {}
11534-
this.request(false, REQUEST_TYPE_POST, REQUEST_TYPE_JSON, this.getBaseUrl() + '/coverage/start', {}, {}, function (url, res, err) {
11555+
this.requestPost(false, '/coverage/start', {}, {}, function (url, res, err) {
1153511556
try {
1153611557
App.onResponse(url, res, err)
1153711558
if (DEBUG) {
@@ -11915,6 +11936,14 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1191511936
const cur = item
1191611937
const pre = list[index - 1] || {} // item.pre = item.pre || list[index - 1] || {}
1191711938
// const ctx = item.ctx = item.ctx || {}
11939+
const ctx = {
11940+
list: list,
11941+
allCount: allCount,
11942+
index: index,
11943+
cur: cur,
11944+
pre: pre,
11945+
ctx: {} // ctx
11946+
}
1191811947

1191911948
var random = item.Random || {}
1192011949
this.parseRandom(req, header, random.config, random.id, true, false, false, function(randomName, constConfig, constJson, constHeader) {
@@ -11955,26 +11984,19 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1195511984
App.log('startTestSingle App.request >> } catch (e) {\n' + e.message)
1195611985
}
1195711986

11958-
App.compareResponse(res, allCount, list, index, item, res.data, isRandom, accountIndex, false, err || otherErr, null, isCross, callback, singleCallback)
11987+
App.compareResponse(res, allCount, list, index, item, res.data, isRandom, accountIndex, false, err || otherErr, null, isCross, callback, singleCallback, caseScript, ctx)
1195911988
}, caseScript)
1196011989

1196111990
}, caseScript)
11962-
}, (caseScript.pre || {}).script, {
11963-
list: list,
11964-
allCount: allCount,
11965-
index: index,
11966-
cur: cur,
11967-
pre: pre,
11968-
ctx: ctx
11969-
})
11991+
}, (caseScript.pre || {}).script, ctx)
1197011992
}
1197111993
catch(e) {
11972-
this.compareResponse(null, allCount, list, index, item, null, isRandom, accountIndex, false, e, null, isCross, callback, singleCallback)
11994+
this.compareResponse(null, allCount, list, index, item, null, isRandom, accountIndex, false, e, null, isCross, callback, singleCallback, caseScript, ctx)
1197311995
}
1197411996

1197511997
},
1197611998

11977-
compareResponse: function (res, allCount, list, index, item, response, isRandom, accountIndex, justRecoverTest, err, ignoreTrend, isCross, callback, singleCallback) {
11999+
compareResponse: function (res, allCount, list, index, item, response, isRandom, accountIndex, justRecoverTest, err, ignoreTrend, isCross, callback, singleCallback, caseScript, ctx) {
1197812000
var it = item || {} //请求异步
1197912001
var cri = this.currentRemoteItem || {} //请求异步
1198012002
var d = (isRandom ? cri.Document : it.Document) || {} //请求异步
@@ -12030,6 +12052,24 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1203012052
var standard = typeof stdd != 'string' ? stdd : (StringUtil.isEmpty(stdd, true) ? null : parseJSON(stdd))
1203112053
tr.compare = JSONResponse.compareResponse(res, standard, this.removeDebugInfo(response) || {}, '', isML, null, null, ignoreTrend) || {}
1203212054
tr.compare.duration = it.durationHint
12055+
12056+
var resRandom = it['Random:res'] || {}
12057+
var resCfg = resRandom.config
12058+
if (StringUtil.isNotEmpty(resCfg)) {
12059+
try {
12060+
this.parseRandom(response, res.headers, resCfg, resRandom.id, true, false, false, function (randomName, constConfig, constJson, constHeader) {
12061+
App.onTestResponse(res, allCount, list, index, it, d, r, tr, response, tr.compare || {}, isRandom, accountIndex, justRecoverTest, isCross, callback, singleCallback);
12062+
}, StringUtil.trim((caseScript.pre || {}).script) + '\n' + StringUtil.trim((caseScript.post || {}).script), ctx, true)
12063+
return
12064+
} catch (e) {
12065+
err = e
12066+
tr.compare = {
12067+
code: JSONResponse.COMPARE_ERROR, //请求出错
12068+
msg: e.message,
12069+
path: ''
12070+
}
12071+
}
12072+
}
1203312073
}
1203412074

1203512075
this.onTestResponse(res, allCount, list, index, it, d, r, tr, response, tr.compare || {}, isRandom, accountIndex, justRecoverTest, isCross, callback, singleCallback);

APIJSON-Java-Server/APIJSONDemo-Jackson/src/main/java/apijson/demo/DemoSQLConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public String gainDBUri() {
5151
return "jdbc:mysql://localhost:3306?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8"; // TODO 改成你自己的,TiDB 可以当成 MySQL 使用,默认端口为 4000
5252
}
5353

54+
// FIXME:配置未生效!
5455
@Override
5556
public String gainDBAccount() {
5657
return "root"; // TODO 改成你自己的

0 commit comments

Comments
 (0)