/
evaluator.go
102 lines (82 loc) · 2.5 KB
/
evaluator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package vars
import (
"regexp"
"strings"
"github.com/jmartin82/mmock/v3/pkg/mock"
)
var varsRegex = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`)
type Evaluator interface {
Eval(req *mock.Request, m *mock.Definition)
}
type ResponseMessageEvaluator struct {
FillerFactory FillerFactory
}
func NewResponseMessageEvaluator(fp FillerFactory) *ResponseMessageEvaluator {
return &ResponseMessageEvaluator{FillerFactory: fp}
}
func (fp ResponseMessageEvaluator) Eval(req *mock.Request, m *mock.Definition) {
requestFiller := fp.FillerFactory.CreateRequestFiller(req, m)
fakeFiller := fp.FillerFactory.CreateFakeFiller()
streamFiller := fp.FillerFactory.CreateStreamFiller()
//replace stream holders for their content
fp.walkAndFill(m, streamFiller.Fill(fp.walkAndGet(m.Response)))
//extract holders
holders := fp.walkAndGet(m.Response)
fp.extractVars(m.Callback.Body, &holders)
//fill holders
vars := requestFiller.Fill(holders)
fp.mergeVars(vars, fakeFiller.Fill(holders))
fp.walkAndFill(m, vars)
}
func (fp ResponseMessageEvaluator) walkAndGet(res mock.Response) []string {
vars := []string{}
for _, header := range res.Headers {
for _, value := range header {
fp.extractVars(value, &vars)
}
}
for _, value := range res.Cookies {
fp.extractVars(value, &vars)
}
fp.extractVars(res.Body, &vars)
return vars
}
func (fp ResponseMessageEvaluator) walkAndFill(m *mock.Definition, vars map[string][]string) {
res := &m.Response
for header, values := range res.Headers {
for i, value := range values {
res.Headers[header][i] = fp.replaceVars(value, vars)
}
}
for cookie, value := range res.Cookies {
res.Cookies[cookie] = fp.replaceVars(value, vars)
}
res.Body = fp.replaceVars(res.Body, vars)
m.Callback.Body = fp.replaceVars(m.Callback.Body, vars)
}
func (fp ResponseMessageEvaluator) replaceVars(input string, vars map[string][]string) string {
return varsRegex.ReplaceAllStringFunc(input, func(value string) string {
varName := strings.Trim(value, "{} ")
// replace the strings
if v, found := vars[varName]; found {
r := v[0]
vars[varName] = v[1:]
return r
}
// replace regexes
return value
})
}
func (fp ResponseMessageEvaluator) extractVars(input string, vars *[]string) {
if m := varsRegex.FindAllString(input, -1); m != nil {
for _, v := range m {
varName := strings.Trim(v, "{} ")
*vars = append(*vars, varName)
}
}
}
func (fp ResponseMessageEvaluator) mergeVars(org map[string][]string, vals map[string][]string) {
for k, v := range vals {
org[k] = v
}
}