-
Notifications
You must be signed in to change notification settings - Fork 0
/
extract.go
99 lines (86 loc) · 2.66 KB
/
extract.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
package venom
import (
"fmt"
"regexp"
"strings"
"unicode"
"github.com/mitchellh/mapstructure"
)
// applyExtracts try to run extract on step, return true if all extracts are OK, false otherwise
func applyExtracts(executorResult *ExecutorResult, step TestStep) assertionsApplied {
var se StepExtracts
var errors []Failure
var failures []Failure
if err := mapstructure.Decode(step, &se); err != nil {
return assertionsApplied{
ok: false,
errors: []Failure{{Value: RemoveNotPrintableChar(fmt.Sprintf("error decoding extracts: %s", err))}},
}
}
isOK := true
for key, pattern := range se.Extracts {
e := *executorResult
if _, ok := e[key]; !ok {
return assertionsApplied{
ok: false,
errors: []Failure{{Value: RemoveNotPrintableChar(fmt.Sprintf("key %s in result is not found", key))}},
}
}
errs, fails := checkExtracts(transformPattern(pattern), fmt.Sprintf("%v", e[key]), executorResult)
if errs != nil {
errors = append(errors, *errs)
isOK = false
}
if fails != nil {
failures = append(failures, *fails)
isOK = false
}
}
return assertionsApplied{
ok: isOK,
errors: errors,
failures: failures,
}
}
var extractPattern, _ = regexp.Compile(`{{[a-zA-Z0-9]+=.*?}}`)
// example:
// in: "result.systemout: foo with a {{myvariable=[a-z]+}} here"
// out: "result.systemout: foo with a (?P<myvariable>[a-z]+) here"
func transformPattern(pattern string) string {
var p = pattern
for _, v := range extractPattern.FindAllString(pattern, -1) {
varname := v[2:strings.Index(v, "=")] // extract "foo from '{{foo=value}}'"
valregex := v[strings.Index(v, "=")+1 : len(v)-2] // extract "value from '{{foo=value}}'"
p = strings.Replace(p, "{{"+varname+"="+valregex+"}}", "(?P<"+varname+">"+valregex+")", -1)
}
return p
}
func checkExtracts(pattern, instring string, executorResult *ExecutorResult) (*Failure, *Failure) {
r := regexp.MustCompile(pattern)
match := r.FindStringSubmatch(instring)
if match == nil {
return &Failure{Value: RemoveNotPrintableChar(fmt.Sprintf("Pattern '%s' does not match string '%s'", pattern, instring))}, nil
}
e := *executorResult
found := true
for i, name := range r.SubexpNames() {
if i == 0 {
continue
}
e[name] = match[i]
}
if !found {
return nil, &Failure{Value: RemoveNotPrintableChar(fmt.Sprintf("pattern '%s' match nothing in result '%s'", pattern, instring))}
}
return nil, nil
}
// RemoveNotPrintableChar removes not printable chararacter from a string
func RemoveNotPrintableChar(in string) string {
m := func(r rune) rune {
if unicode.IsPrint(r) || unicode.IsSpace(r) || unicode.IsPunct(r) {
return r
}
return ' '
}
return strings.Map(m, in)
}