github.com/mundipagg/tracer-splunk-writer@v1.0.6/json/encoder/struct_test.go (about)

     1  package encoder
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"reflect"
     7  	"strings"
     8  	"testing"
     9  	"unsafe"
    10  
    11  	jsoniter "github.com/json-iterator/go"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestStruct_IsEmpty(t *testing.T) {
    16  	t.Parallel()
    17  	is := assert.New(t)
    18  	subject := &Struct{}
    19  	input := struct{}{}
    20  	pointer := reflect.ValueOf(&input).Pointer()
    21  	is.False(subject.IsEmpty(unsafe.Pointer(pointer)))
    22  }
    23  
    24  type V struct {
    25  	A int
    26  }
    27  
    28  func (V) MarshalJSON() ([]byte, error) {
    29  	return jsoniter.Marshal("custom")
    30  }
    31  
    32  func TestStruct_Encode(t *testing.T) {
    33  	t.Parallel()
    34  	t.Run("when the value implements the json.Marshaller interface", func(t *testing.T) {
    35  		t.Parallel()
    36  		is := assert.New(t)
    37  		input := V{15}
    38  		called := 0
    39  		subject := &Struct{
    40  			Strategy: func(s string) string {
    41  				called++
    42  				return strings.ToLower(s)
    43  			},
    44  			Type: reflect.TypeOf(input),
    45  		}
    46  		buf := &bytes.Buffer{}
    47  		stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100)
    48  		subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream)
    49  		stream.Flush()
    50  		is.Equal(`"custom"`, buf.String(), "it should change the name of the field")
    51  		is.Equal(0, called, "it should not call the strategy ")
    52  	})
    53  	t.Run("when the value implements the error interface", func(t *testing.T) {
    54  		t.Parallel()
    55  		is := assert.New(t)
    56  		input := errors.New("error")
    57  		called := 0
    58  		subject := &Struct{
    59  			Strategy: func(s string) string {
    60  				called++
    61  				return strings.ToLower(s)
    62  			},
    63  			Type: reflect.TypeOf(input),
    64  		}
    65  		buf := &bytes.Buffer{}
    66  
    67  		stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100)
    68  		ptr := reflect.New(reflect.TypeOf(input))
    69  		ptr.Elem().Set(reflect.ValueOf(input))
    70  		subject.Encode(unsafe.Pointer(ptr.Pointer()), stream)
    71  		stream.Flush()
    72  		is.Equal(`"error"`, buf.String(), "it should change the name of the field")
    73  		is.Equal(0, called, "it should not call the strategy ")
    74  	})
    75  	t.Run("when the field does not have a json tag", func(t *testing.T) {
    76  		t.Parallel()
    77  		is := assert.New(t)
    78  		input := struct {
    79  			A int
    80  			b int
    81  		}{
    82  			A: 15,
    83  			b: 15,
    84  		}
    85  		called := 0
    86  		subject := &Struct{
    87  			Strategy: func(s string) string {
    88  				called++
    89  				return strings.ToLower(s)
    90  			},
    91  			Type: reflect.TypeOf(input),
    92  		}
    93  		buf := &bytes.Buffer{}
    94  		stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100)
    95  		subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream)
    96  		stream.Flush()
    97  		is.Equal(`{"a":15}`, buf.String(), "it should change the name of the field")
    98  		is.Equal(1, called, "it should call the strategy exactly one time")
    99  	})
   100  	t.Run("when the field does not have omitempty on it's tag", func(t *testing.T) {
   101  		t.Parallel()
   102  		is := assert.New(t)
   103  		input := struct {
   104  			A int `json:"SuperParameter"`
   105  		}{
   106  			A: 15,
   107  		}
   108  		called := 0
   109  		subject := &Struct{
   110  			Strategy: func(s string) string {
   111  				called++
   112  				return strings.ToUpper(s)
   113  			},
   114  			Type: reflect.TypeOf(input),
   115  		}
   116  		buf := &bytes.Buffer{}
   117  		stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100)
   118  		subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream)
   119  		stream.Flush()
   120  		is.Equal(`{"SUPERPARAMETER":15}`, buf.String(), "it should change the name of the field")
   121  		is.Equal(1, called, "it should call the strategy exactly one time")
   122  	})
   123  	t.Run("when the field does have omitempty on it's tag", func(t *testing.T) {
   124  		t.Parallel()
   125  		t.Run("but the field is not empty", func(t *testing.T) {
   126  			t.Parallel()
   127  			is := assert.New(t)
   128  			v := 16
   129  			input := struct {
   130  				A int  `json:"SuperParameterA"`
   131  				B *int `json:"SuperParameterB,omitempty"`
   132  				C int  `json:"SuperParameterC,omitempty"`
   133  				D *int `json:"SuperParameterD,omitempty"`
   134  				E int  `json:"SuperParameterE"`
   135  			}{
   136  				A: 15,
   137  				D: &v,
   138  				E: 17,
   139  			}
   140  			called := 0
   141  			subject := &Struct{
   142  				Strategy: func(s string) string {
   143  					called++
   144  					return strings.ToUpper(s)
   145  				},
   146  				Type: reflect.TypeOf(input),
   147  			}
   148  			buf := &bytes.Buffer{}
   149  			stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100)
   150  			subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream)
   151  			stream.Flush()
   152  			is.Equal(`{"SUPERPARAMETERA":15,"SUPERPARAMETERD":16,"SUPERPARAMETERE":17}`, buf.String(), "it should change the name of the field")
   153  			is.Equal(3, called, "it should call the strategy exactly three times")
   154  		})
   155  		t.Run("and the field is empty", func(t *testing.T) {
   156  			t.Parallel()
   157  			is := assert.New(t)
   158  			input := struct {
   159  				A *int `json:"SuperParameter,omitempty"`
   160  			}{
   161  				A: nil,
   162  			}
   163  			called := 0
   164  			subject := &Struct{
   165  				Strategy: func(s string) string {
   166  					called++
   167  					return strings.ToUpper(s)
   168  				},
   169  				Type: reflect.TypeOf(input),
   170  			}
   171  			buf := &bytes.Buffer{}
   172  			stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100)
   173  			subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream)
   174  			stream.Flush()
   175  			is.Equal(`{}`, buf.String(), "it should change the name of the field")
   176  			is.Equal(0, called, "it should not call the strategy")
   177  		})
   178  	})
   179  }