github.com/webdestroya/awsmocker@v0.2.6/jmesutil.go (about)

     1  package awsmocker
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/jmespath/go-jmespath"
     8  )
     9  
    10  // this will normalize a value to allow it to be compared more easily against another one
    11  // used for JMES path, because json numbers are float64 so you cant compare to other value types
    12  func jmesValueNormalize(value any) any {
    13  	if value == nil {
    14  		return nil
    15  	}
    16  
    17  	// switch v := value.(type) {
    18  	// case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
    19  	// 	return fmt.Sprintf("%d", v)
    20  	// case float32:
    21  	// 	return strconv.FormatFloat(float64(v), 'f', -1, 64)
    22  	// case float64:
    23  	// 	return strconv.FormatFloat(float64(v), 'f', -1, 64)
    24  	// case string, bool:
    25  	// 	return v
    26  	// default:
    27  	// 	return v
    28  	// }
    29  	switch v := value.(type) {
    30  	case string, bool, nil, float64:
    31  		return v
    32  	case int:
    33  		return float64(v)
    34  	case int8:
    35  		return float64(v)
    36  	case int16:
    37  		return float64(v)
    38  	case int32:
    39  		return float64(v)
    40  	case int64:
    41  		return float64(v)
    42  	case uint:
    43  		return float64(v)
    44  	case uint8:
    45  		return float64(v)
    46  	case uint16:
    47  		return float64(v)
    48  	case uint32:
    49  		return float64(v)
    50  	case uint64:
    51  		return float64(v)
    52  	case float32:
    53  		return float64(v)
    54  	case func(any) bool:
    55  		return v
    56  	default:
    57  		panic("jmes expressions should evaluate to a string/bool/number/nil. Advanced checks should use a function")
    58  	}
    59  
    60  }
    61  
    62  // Performs a JMES Expression match on the object.
    63  // The expected value should be a scalar or a function that takes a single any
    64  // and returns a boolean
    65  // the value returned from the jmes expression should equal the expected value
    66  // all numerical values will be casted to a float64 (as that is what json numbers are treated as)
    67  func JMESMatch(obj any, expression string, expected any) bool {
    68  
    69  	resp, err := jmespath.Search(expression, obj)
    70  	if err != nil {
    71  		panic(fmt.Errorf("Failed to parse expression: '%s': %w", expression, err))
    72  	}
    73  
    74  	exp := jmesValueNormalize(expected)
    75  
    76  	funcCheck, ok := exp.(func(any) bool)
    77  	if ok {
    78  		return funcCheck(resp)
    79  	}
    80  
    81  	return reflect.DeepEqual(resp, exp)
    82  }