mqls_doaction.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package odbcmql
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. "testing"
  9. "git.wecise.com/wecise/odb-go/odb"
  10. "gitee.com/wecisecode/util/cast"
  11. "gitee.com/wecisecode/util/merrs"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. func DoActionMatch(t *testing.T, args []any, mql string, rtn *odb.Result, toption *OnErrorOption) (breakup bool, seriouserror bool, err error) {
  15. if len(args) < 2 {
  16. s := "match(Kn,Mn) 需要至少两个参数"
  17. err = merrs.New("%s", s)
  18. assert.Nil(t, s, err)
  19. seriouserror = true
  20. breakup = true
  21. return
  22. }
  23. ks := []string{}
  24. ms := []any{}
  25. i := 0
  26. for ; i+1 < len(args); i += 2 {
  27. k := strings.TrimSpace(cast.ToString(args[i]))
  28. ks = append(ks, k)
  29. var m any
  30. switch arg := args[i+1].(type) {
  31. case string:
  32. if regexp.MustCompile(`^\(\?[^\)]*\).*`).MatchString(arg) {
  33. r, e := regexp.Compile(arg)
  34. if e != nil {
  35. s := "match参数正则表达式错误:" + e.Error()
  36. err = merrs.New("%s", s)
  37. assert.Nil(t, s, err)
  38. seriouserror = true
  39. breakup = true
  40. return
  41. }
  42. m = r
  43. }
  44. }
  45. if m == nil {
  46. m = fmt.Sprintf("%#v", args[i+1])
  47. }
  48. ms = append(ms, m)
  49. }
  50. if i > len(args) {
  51. err = merrs.New("match(Kn,Mn) 参数 Kn,Mn 需要成对出现")
  52. assert.Nil(t, "参数错误", err)
  53. seriouserror = true
  54. breakup = true
  55. return
  56. }
  57. x, matchingvalues := MatchValues(rtn, ks, ms)
  58. if x == 0 {
  59. if len(rtn.Data) == 0 {
  60. err = merrs.New("%s", "没有找到记录与期望值不符")
  61. } else {
  62. argsbs, _ := json.MarshalIndent(args, "", " ")
  63. matchingbs, _ := json.MarshalIndent(matchingvalues, "", " ")
  64. err = merrs.NewError(fmt.Sprint("共", len(rtn.Data), "记录,没有找到记录与期望值不符"),
  65. merrs.SSMaps{{"mql": mql},
  66. {"match args": fmt.Sprint(string(argsbs))},
  67. {"lastmatchingvalues": string(matchingbs)}})
  68. }
  69. if toption.regex[OnErrorBreak] != nil && toption.regex[OnErrorBreak].MatchString(err.Error()) {
  70. if toption.regex[OnErrorBreak] == matchall && !toption.noerrorinfo {
  71. logger.Info("error:", err)
  72. }
  73. breakup = true
  74. return
  75. }
  76. if toption.regex[OnErrorIgnore] != nil && toption.regex[OnErrorIgnore].MatchString(err.Error()) {
  77. // 直接输出错误信息,不返回错误信息,不中断循环, 不在 testing.T 中报告错误,不中断测试
  78. if toption.regex[OnErrorIgnore] == matchall && !toption.noerrorinfo {
  79. logger.Info("pass_with_error:", err)
  80. }
  81. err = nil
  82. breakup = true
  83. return
  84. }
  85. if !assert.Nil(t, "error", err) {
  86. // 不直接输出错误信息,返回错误信息,中断循环, 在 testing.T 中报告错误,中断测试
  87. breakup = true
  88. return
  89. }
  90. }
  91. return
  92. }
  93. func DoActionEqual(t *testing.T, toption *OnErrorOption, result *odb.Result, args ...string) (breakup bool, seriouserror bool, err error) {
  94. if len(args) < 3 {
  95. err = merrs.New("%s", "equal(N,F,V) 需要三个参数")
  96. assert.Nil(t, "参数错误", err)
  97. seriouserror = true
  98. breakup = true
  99. return
  100. }
  101. n := cast.ToInt(strings.TrimSpace(args[0]))
  102. for kvi := 1; kvi+1 < len(args); kvi += 2 {
  103. field := strings.TrimSpace(args[kvi])
  104. value := strings.TrimSpace(args[kvi+1])
  105. if len(value) > 1 && value[0] == '"' && value[len(value)-1] == '"' {
  106. x, e := strconv.Unquote(value)
  107. if e != nil {
  108. err = merrs.New("%s V:%s", "equal(N,F,V) 参数 V 格式错误", value)
  109. assert.Nil(t, "参数错误", err)
  110. seriouserror = true
  111. breakup = true
  112. return
  113. }
  114. value = x
  115. }
  116. if n < 0 && result.Meta != nil {
  117. dat := result.Meta
  118. breakup, seriouserror, err = DeepEqual(t, toption, dat, field, value)
  119. if breakup {
  120. return
  121. }
  122. } else if len(result.Data) > n && result.Data[n] != nil {
  123. dat := result.Data[n]
  124. breakup, seriouserror, err = DeepEqual(t, toption, dat, field, value)
  125. if breakup {
  126. return
  127. }
  128. } else {
  129. err = merrs.New("%s", fmt.Sprint("字段 ", field, " 实际值(不存在)与期望值(", value, ")不符"))
  130. if toption.regex[OnErrorBreak] != nil && toption.regex[OnErrorBreak].MatchString(err.Error()) {
  131. if toption.regex[OnErrorBreak] == matchall && !toption.noerrorinfo {
  132. logger.Info("error:", err)
  133. }
  134. breakup = true
  135. return
  136. }
  137. if toption.regex[OnErrorIgnore] != nil && toption.regex[OnErrorIgnore].MatchString(err.Error()) {
  138. // 直接输出错误信息,不返回错误信息,不中断循环, 不在 testing.T 中报告错误,不中断测试
  139. if toption.regex[OnErrorIgnore] == matchall && !toption.noerrorinfo {
  140. logger.Info("pass_with_error:", err)
  141. }
  142. err = nil
  143. return
  144. }
  145. if !assert.Equal(t, value, "", err) {
  146. // 不直接输出错误信息,返回错误信息,中断循环, 在 testing.T 中报告错误,中断测试
  147. return
  148. }
  149. }
  150. }
  151. return
  152. }
  153. func DeepEqual(t *testing.T, toption *OnErrorOption, dat map[string]any, field, value string) (breakup bool, seriouserror bool, err error) {
  154. kks := strings.Split(field, ".")
  155. kki := len(kks)
  156. v := ""
  157. var vv any
  158. for ; vv == nil && kki >= 1; kki-- {
  159. kk := strings.Join(kks[:kki], ".")
  160. vv = dat[kk]
  161. for ; vv != nil && kki < len(kks); kki++ {
  162. switch mv := vv.(type) {
  163. case map[string]any:
  164. vv = mv[kks[kki]]
  165. if vv == nil {
  166. if kks[kki] == "len" {
  167. vv = len(mv)
  168. }
  169. }
  170. case map[string][]string:
  171. vvs := mv[kks[kki]]
  172. if vvs == nil {
  173. if kks[kki] == "len" {
  174. vv = len(mv)
  175. }
  176. } else {
  177. vv = vvs
  178. }
  179. case map[string][]any:
  180. vvs := mv[kks[kki]]
  181. if vvs == nil {
  182. if kks[kki] == "len" {
  183. vv = len(mv)
  184. }
  185. } else {
  186. vv = vvs
  187. }
  188. case []any:
  189. if kks[kki] == "len" {
  190. vv = len(mv)
  191. } else {
  192. sik := strings.TrimSpace(kks[kki])
  193. ik, e := strconv.Atoi(sik)
  194. if e != nil {
  195. err = merrs.New("%s V:%s", "equal(N,F,V) 参数 V 格式错误", field)
  196. assert.Nil(t, "参数错误", err)
  197. seriouserror = true
  198. breakup = true
  199. return
  200. }
  201. vv = mv[ik]
  202. }
  203. case []string:
  204. if kks[kki] == "len" {
  205. vv = len(mv)
  206. } else {
  207. sik := strings.TrimSpace(kks[kki])
  208. ik, e := strconv.Atoi(sik)
  209. if e != nil {
  210. err = merrs.New("%s V:%s", "equal(N,F,V) 参数 V 格式错误", field)
  211. assert.Nil(t, "参数错误", err)
  212. seriouserror = true
  213. breakup = true
  214. return
  215. }
  216. vv = mv[ik]
  217. }
  218. }
  219. }
  220. }
  221. v = fmt.Sprint(vv)
  222. if v != value {
  223. err = merrs.New("%s", fmt.Sprint("字段 ", field, " 实际值(", v, ")与期望值(", value, ")不符"))
  224. if toption.regex[OnErrorBreak] != nil && toption.regex[OnErrorBreak].MatchString(err.Error()) {
  225. if toption.regex[OnErrorBreak] == matchall && !toption.noerrorinfo {
  226. logger.Info("error:", err)
  227. }
  228. breakup = true
  229. return
  230. }
  231. if toption.regex[OnErrorIgnore] != nil && toption.regex[OnErrorIgnore].MatchString(err.Error()) {
  232. // 直接输出错误信息,不返回错误信息,不中断循环, 不在 testing.T 中报告错误,不中断测试
  233. if toption.regex[OnErrorIgnore] == matchall && !toption.noerrorinfo {
  234. logger.Info("pass_with_error:", err)
  235. }
  236. err = nil
  237. return
  238. }
  239. if !assert.Equal(t, value, v, err) {
  240. breakup = true
  241. return
  242. }
  243. }
  244. return
  245. }