github.com/akamai/AkamaiOPEN-edgegrid-golang@v1.2.2/jsonhooks-v1/jsonhooks_test.go (about)

     1  package jsonhooks
     2  
     3  import (
     4  	"encoding/json"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  type Optionals struct {
    12  	Sr string `json:"sr"`
    13  	So string `json:"so,omitempty"`
    14  	Sw string `json:"-"`
    15  
    16  	Ir int `json:"omitempty"` // actually named omitempty, not an option
    17  	Io int `json:"io,omitempty"`
    18  
    19  	Slr []string `json:"slr,random"`
    20  	Slo []string `json:"slo,omitempty"`
    21  
    22  	Mr map[string]interface{} `json:"mr"`
    23  	Mo map[string]interface{} `json:",omitempty"`
    24  
    25  	Fr float64 `json:"fr"`
    26  	Fo float64 `json:"fo,omitempty"`
    27  
    28  	Br bool `json:"br"`
    29  	Bo bool `json:"bo,omitempty"`
    30  
    31  	Ur uint `json:"ur"`
    32  	Uo uint `json:"uo,omitempty"`
    33  
    34  	Str struct{} `json:"str"`
    35  	Sto struct{} `json:"sto,omitempty"`
    36  }
    37  
    38  type MixedTypes struct {
    39  	I  int     `json:"I"`
    40  	B  bool    `json:"B"`
    41  	F  float64 `json:"F"`
    42  	S  string  `json:"S"`
    43  	St struct {
    44  		Foo int    `json:"Foo"`
    45  		Bar string `json:"Bar"`
    46  	} `json:"St"`
    47  	A []string `json:"A"`
    48  }
    49  
    50  type WithHooks MixedTypes
    51  
    52  func (hooks *WithHooks) PreMarshalJSON() error {
    53  	hooks.I *= 1000
    54  	hooks.B = !hooks.B
    55  	hooks.F *= 1.1
    56  	hooks.S = strings.ToUpper(hooks.S)
    57  	hooks.St.Foo *= 2000
    58  	hooks.St.Bar = strings.ToUpper(hooks.St.Bar)
    59  	for key, val := range hooks.A {
    60  		hooks.A[key] = strings.ToUpper(val)
    61  	}
    62  
    63  	return nil
    64  }
    65  
    66  func (hooks *WithHooks) PostUnmarshalJSON() error {
    67  	hooks.I /= 1000
    68  	hooks.B = !hooks.B
    69  	hooks.F /= 1.1
    70  	hooks.S = strings.ToLower(hooks.S)
    71  	hooks.St.Foo /= 2000
    72  	hooks.St.Bar = strings.ToLower(hooks.St.Bar)
    73  	for key, val := range hooks.A {
    74  		hooks.A[key] = strings.ToLower(val)
    75  	}
    76  
    77  	return nil
    78  }
    79  
    80  func TestMarshalCompat(t *testing.T) {
    81  	var o Optionals
    82  	o.Sw = "something"
    83  	o.Mr = map[string]interface{}{}
    84  	o.Mo = map[string]interface{}{}
    85  
    86  	expected, _ := json.Marshal(o)
    87  	actual, err := Marshal(o)
    88  
    89  	assert.NoError(t, err)
    90  	assert.Equal(
    91  		t,
    92  		expected,
    93  		actual,
    94  	)
    95  }
    96  
    97  func TestUnmarshalCompat(t *testing.T) {
    98  	data := `{
    99  		"sr": "",
   100  				"omitempty": 0,
   101  				"slr": null,
   102  				"mr": {},
   103  		"fr": 0,
   104  				"br": false,
   105  				"ur": 0,
   106  				"str": {},
   107  		"sto": {}
   108  	}`
   109  
   110  	expected := &Optionals{}
   111  	_ = json.Unmarshal([]byte(data), expected)
   112  
   113  	actual := &Optionals{}
   114  	err := Unmarshal([]byte(data), actual)
   115  
   116  	assert.NoError(t, err)
   117  	assert.Equal(
   118  		t,
   119  		expected,
   120  		actual,
   121  	)
   122  }
   123  
   124  func TestImplementsPreJSONMarshaler(t *testing.T) {
   125  	noHooks := &MixedTypes{}
   126  	withHooks := &WithHooks{}
   127  
   128  	assert.False(t, ImplementsPreJSONMarshaler(noHooks))
   129  	assert.True(t, ImplementsPreJSONMarshaler(withHooks))
   130  }
   131  
   132  func TestImplementsPostJSONUnmarshaler(t *testing.T) {
   133  	noHooks := &MixedTypes{}
   134  	withHooks := &WithHooks{}
   135  
   136  	assert.False(t, ImplementsPostJSONUnmarshaler(noHooks))
   137  	assert.True(t, ImplementsPostJSONUnmarshaler(withHooks))
   138  }
   139  
   140  func TestPreJSONMarshal(t *testing.T) {
   141  	noHooks := &MixedTypes{
   142  		I: 1,
   143  		B: true,
   144  		F: 1.0,
   145  		S: "testing",
   146  		St: struct {
   147  			Foo int    `json:"Foo"`
   148  			Bar string `json:"Bar"`
   149  		}{2, "test"},
   150  		A: []string{"one", "two", "three"},
   151  	}
   152  
   153  	withHooks := (*WithHooks)(noHooks)
   154  
   155  	expected, _ := json.Marshal(&MixedTypes{
   156  		I: 1 * 1000,
   157  		B: !true,
   158  		F: 1.0 * 1.1,
   159  		S: "TESTING",
   160  		St: struct {
   161  			Foo int    `json:"Foo"`
   162  			Bar string `json:"Bar"`
   163  		}{2 * 2000, "TEST"},
   164  		A: []string{"ONE", "TWO", "THREE"},
   165  	})
   166  
   167  	gojson, _ := json.Marshal(withHooks)
   168  	actualNoHooks, _ := Marshal(noHooks)
   169  	actualWithHooks, err := Marshal(withHooks)
   170  
   171  	assert.NoError(t, err)
   172  	assert.Equal(t, string(gojson), string(actualNoHooks))
   173  	assert.NotEqual(t, string(gojson), string(actualWithHooks))
   174  	assert.NotEqual(t, string(actualNoHooks), string(actualWithHooks))
   175  	assert.Equal(t, string(expected), string(actualWithHooks))
   176  }
   177  
   178  func TestPostJSONUnmarshal(t *testing.T) {
   179  	expected := &WithHooks{
   180  		I: 1,
   181  		B: true,
   182  		F: 1.0,
   183  		S: "testing",
   184  		St: struct {
   185  			Foo int    `json:"Foo"`
   186  			Bar string `json:"Bar"`
   187  		}{2, "test"},
   188  		A: []string{"one", "two", "three"},
   189  	}
   190  
   191  	data := []byte(`{"I":1000,"B":false,"F":1.1,"S":"TESTING","St":{"Foo":4000,"Bar":"TEST"},"A":["ONE","TWO","THREE"]}`)
   192  
   193  	gojson := &MixedTypes{}
   194  	_ = json.Unmarshal(
   195  		data,
   196  		gojson,
   197  	)
   198  
   199  	withHooks := &WithHooks{}
   200  	err := Unmarshal(data, withHooks)
   201  	assert.NoError(t, err)
   202  
   203  	withoutHooks := &MixedTypes{}
   204  	err = Unmarshal(data, withoutHooks)
   205  
   206  	assert.NoError(t, err)
   207  	assert.NotEqual(t, gojson, withHooks)
   208  	assert.NotEqual(t, expected, withoutHooks)
   209  	assert.Equal(t, expected, withHooks)
   210  }