github.com/icyphox/x@v0.0.355-0.20220311094250-029bd783e8b8/snapshotx/snapshot.go (about)

     1  package snapshotx
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/tidwall/gjson"
    10  
    11  	"github.com/ory/x/stringslice"
    12  
    13  	"github.com/bradleyjkemp/cupaloy/v2"
    14  	"github.com/stretchr/testify/require"
    15  	"github.com/tidwall/sjson"
    16  )
    17  
    18  func SnapshotTExcept(t *testing.T, actual interface{}, except []string) {
    19  	compare, err := json.MarshalIndent(actual, "", "  ")
    20  	require.NoError(t, err, "%+v", actual)
    21  	for _, e := range except {
    22  		compare, err = sjson.DeleteBytes(compare, e)
    23  		require.NoError(t, err, "%s", e)
    24  	}
    25  
    26  	cupaloy.New(
    27  		cupaloy.CreateNewAutomatically(true),
    28  		cupaloy.FailOnUpdate(true),
    29  		cupaloy.SnapshotFileExtension(".json"),
    30  	).SnapshotT(t, compare)
    31  }
    32  
    33  func deleteMatches(t *testing.T, key string, result gjson.Result, matches []string, parents []string, content []byte) []byte {
    34  	path := parents
    35  	if key != "" {
    36  		path = append(parents, key)
    37  	}
    38  
    39  	if result.IsObject() {
    40  		result.ForEach(func(key, value gjson.Result) bool {
    41  			content = deleteMatches(t, key.String(), value, matches, path, content)
    42  			return true
    43  		})
    44  	} else if result.IsArray() {
    45  		var i int
    46  		result.ForEach(func(_, value gjson.Result) bool {
    47  			content = deleteMatches(t, fmt.Sprintf("%d", i), value, matches, path, content)
    48  			i++
    49  			return true
    50  		})
    51  	}
    52  
    53  	if stringslice.Has(matches, key) {
    54  		content, err := sjson.DeleteBytes(content, strings.Join(path, "."))
    55  		require.NoError(t, err)
    56  		return content
    57  	}
    58  
    59  	return content
    60  }
    61  
    62  // SnapshotTExceptMatchingKeys works like SnapshotTExcept but deletes keys that match the given matches recursively.
    63  //
    64  // So instead of having deeply nested keys like `foo.bar.baz.0.key_to_delete` you can have `key_to_delete` and
    65  // all occurences of `key_to_delete` will be removed.
    66  func SnapshotTExceptMatchingKeys(t *testing.T, actual interface{}, matches []string) {
    67  	compare, err := json.MarshalIndent(actual, "", "  ")
    68  	require.NoError(t, err, "%+v", actual)
    69  
    70  	parsed := gjson.ParseBytes(compare)
    71  	require.True(t, parsed.IsObject() || parsed.IsArray())
    72  	compare = deleteMatches(t, "", parsed, matches, []string{}, compare)
    73  
    74  	cupaloy.New(
    75  		cupaloy.CreateNewAutomatically(true),
    76  		cupaloy.FailOnUpdate(true),
    77  		cupaloy.SnapshotFileExtension(".json"),
    78  	).SnapshotT(t, compare)
    79  }