github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/test/should/json.go (about)

     1  package should
     2  
     3  import (
     4  	"encoding/json"
     5  	"github.com/v2pro/plz/test"
     6  	"github.com/v2pro/plz/test/testify/assert"
     7  	"runtime"
     8  	"reflect"
     9  )
    10  
    11  func JsonEqual(expected string, actual interface{}) {
    12  	t := test.CurrentT()
    13  	test.Helper()
    14  	var expectedObj interface{}
    15  	err := json.Unmarshal([]byte(expected), &expectedObj)
    16  	if err != nil {
    17  		t.Error("expected json is invalid: " + err.Error())
    18  		return
    19  	}
    20  	var actualJson []byte
    21  	switch actualVal := actual.(type) {
    22  	case string:
    23  		actualJson = []byte(actualVal)
    24  	case []byte:
    25  		actualJson = actualVal
    26  	default:
    27  		actualJson, err = json.Marshal(actual)
    28  		t.Error("actual can not marshal to json: " + err.Error())
    29  		return
    30  	}
    31  	var actualObj interface{}
    32  	err = json.Unmarshal(actualJson, &actualObj)
    33  	if err != nil {
    34  		t.Log(string(actualJson))
    35  		t.Error("actual json is invalid: " + err.Error())
    36  		return
    37  	}
    38  	maskAnything(expectedObj, actualObj)
    39  	if assert.Equal(t, expectedObj, actualObj) {
    40  		return
    41  	}
    42  	test.Helper()
    43  	_, file, line, ok := runtime.Caller(1)
    44  	if !ok {
    45  		t.Error("check failed")
    46  		return
    47  	}
    48  	t.Log(string(actualJson))
    49  	t.Error(test.ExtractFailedLines(file, line))
    50  }
    51  
    52  func maskAnything(expected interface{}, actual interface{}) {
    53  	switch reflect.TypeOf(expected).Kind() {
    54  	case reflect.Map:
    55  		if reflect.ValueOf(actual).Kind() != reflect.Map {
    56  			return
    57  		}
    58  		expectedVal := reflect.ValueOf(expected)
    59  		actualVal := reflect.ValueOf(actual)
    60  		keys := expectedVal.MapKeys()
    61  		for _, key := range keys {
    62  			elem := expectedVal.MapIndex(key).Interface()
    63  			if elem == "ANYTHING" {
    64  				actualVal.SetMapIndex(key, reflect.ValueOf("ANYTHING"))
    65  				continue
    66  			}
    67  			maskAnything(elem, actualVal.MapIndex(key).Interface())
    68  		}
    69  	}
    70  }