Skip to content

Commit

Permalink
exploring support for type matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
gkampitakis committed Jun 18, 2023
1 parent a2cf7ae commit 7930298
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
12 changes: 12 additions & 0 deletions examples/__snapshots__/matchJSON_test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,15 @@
}
}
---

[TestMatchers/type_matcher - 1]
{
"data": "<Type:float64>"
}
---

[TestMatchers/type_matcher - 2]
{
"metadata": "<Type:map[string]interface {}>"
}
---
9 changes: 9 additions & 0 deletions examples/matchJSON_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,13 @@ func TestMatchers(t *testing.T) {

snaps.MatchJSON(t, body, match.Any("data.createdAt"))
})

t.Run("type matcher", func(t *testing.T) {
snaps.MatchJSON(t, `{"data":10}`, match.Type[float64]("data"))
snaps.MatchJSON(
t,
`{"metadata":{"timestamp":"1687108093142"}}`,
match.Type[map[string]interface{}]("metadata"),
)
})
}
75 changes: 75 additions & 0 deletions match/type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package match

import (
"errors"
"fmt"

"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)

type typeMatcher[T any] struct {
paths []string
errOnMissingPath bool
name string
_type interface{}
}

func Type[T any](paths ...string) *typeMatcher[T] {
return &typeMatcher[T]{
paths: paths,
errOnMissingPath: true,
name: "Type",
_type: *new(T),
}
}

// ErrOnMissingPath determines if matcher will fail in case of trying to access a json path
// that doesn't exist
func (t *typeMatcher[T]) ErrOnMissingPath(e bool) *typeMatcher[T] {
t.errOnMissingPath = e
return t
}

func (t typeMatcher[T]) JSON(s []byte) ([]byte, []MatcherError) {
var errs []MatcherError
json := s

for _, path := range t.paths {
r := gjson.GetBytes(json, path)
if !r.Exists() {
if t.errOnMissingPath {
errs = append(errs, MatcherError{
Reason: errors.New("path does not exist"),
Matcher: t.name,
Path: path,
})
}
continue
}

_, ok := r.Value().(T)
value := fmt.Sprintf("<Type:%T>", *new(T))
if !ok {
value = fmt.Sprintf("<Type:%T>", r.Value())
}

j, err := sjson.SetBytesOptions(json, path, value, &sjson.Options{
Optimistic: true,
ReplaceInPlace: true,
})
if err != nil {
errs = append(errs, MatcherError{
Reason: err,
Matcher: t.name,
Path: path,
})

continue
}

json = j
}

return json, errs
}

0 comments on commit 7930298

Please sign in to comment.