-
Notifications
You must be signed in to change notification settings - Fork 6
/
any.go
118 lines (94 loc) · 2.51 KB
/
any.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package match
import (
"bytes"
"github.com/gkampitakis/go-snaps/match/internal/yaml"
"github.com/goccy/go-yaml/parser"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
type anyMatcher struct {
paths []string
placeholder any
errOnMissingPath bool
name string
}
func (a *anyMatcher) matcherError(err error, path string) MatcherError {
return MatcherError{
Reason: err,
Matcher: a.name,
Path: path,
}
}
/*
Any matcher acts as a placeholder for any value
It replaces any targeted path with a placeholder string
Any("user.name", "user.email")
// or for yaml
Any("$.user.name", "$.user.email")
*/
func Any(paths ...string) *anyMatcher {
return &anyMatcher{
errOnMissingPath: true,
placeholder: "<Any value>",
paths: paths,
name: "Any",
}
}
// Placeholder allows to define the placeholder value for Any matcher
func (a *anyMatcher) Placeholder(p any) *anyMatcher {
a.placeholder = p
return a
}
// ErrOnMissingPath determines if matcher will fail in case of trying to access a path
// that doesn't exist
func (a *anyMatcher) ErrOnMissingPath(e bool) *anyMatcher {
a.errOnMissingPath = e
return a
}
// YAML is intended to be called internally on snaps.MatchYAML for applying Any matchers
func (a anyMatcher) YAML(b []byte) ([]byte, []MatcherError) {
var errs []MatcherError
f, err := parser.ParseBytes(b, parser.ParseComments)
if err != nil {
return b, []MatcherError{a.matcherError(err, "*")}
}
for _, p := range a.paths {
path, _, exists, err := yaml.Get(f, p)
if err != nil {
errs = append(errs, a.matcherError(err, p))
continue
}
if !exists {
if a.errOnMissingPath {
errs = append(errs, a.matcherError(errPathNotFound, p))
}
continue
}
if err := yaml.Update(f, path, a.placeholder); err != nil {
errs = append(errs, a.matcherError(err, p))
continue
}
}
return yaml.MarshalFile(f, bytes.HasSuffix(b, []byte("\n"))), errs
}
// JSON is intended to be called internally on snaps.MatchJSON for applying Any matchers
func (a anyMatcher) JSON(b []byte) ([]byte, []MatcherError) {
var errs []MatcherError
json := b
for _, path := range a.paths {
r := gjson.GetBytes(json, path)
if !r.Exists() {
if a.errOnMissingPath {
errs = append(errs, a.matcherError(errPathNotFound, path))
}
continue
}
j, err := sjson.SetBytesOptions(json, path, a.placeholder, setJSONOptions)
if err != nil {
errs = append(errs, a.matcherError(err, path))
continue
}
json = j
}
return json, errs
}