github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_encoder_native_test.go (about)

     1  package jzon
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  	"testing"
     7  	"unsafe"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestValEncoder_Bool(t *testing.T) {
    13  	f := func(t *testing.T, b bool) {
    14  		checkEncodeValueWithStandard(t, b, nil)
    15  	}
    16  	t.Run("true", func(t *testing.T) {
    17  		f(t, true)
    18  	})
    19  	t.Run("false", func(t *testing.T) {
    20  		f(t, false)
    21  	})
    22  	t.Run("nil ptr", func(t *testing.T) {
    23  		checkEncodeValueWithStandard(t, (*bool)(nil), nil)
    24  	})
    25  	t.Run("ptr", func(t *testing.T) {
    26  		b := true
    27  		checkEncodeValueWithStandard(t, &b, nil)
    28  	})
    29  }
    30  
    31  func TestValEncoder_Bool_Kind(t *testing.T) {
    32  	type Bool bool
    33  	f := func(t *testing.T, b Bool) {
    34  		checkEncodeValueWithStandard(t, b, nil)
    35  	}
    36  	t.Run("true", func(t *testing.T) {
    37  		f(t, true)
    38  	})
    39  	t.Run("false", func(t *testing.T) {
    40  		f(t, false)
    41  	})
    42  	t.Run("nil ptr", func(t *testing.T) {
    43  		checkEncodeValueWithStandard(t, (*Bool)(nil), nil)
    44  	})
    45  	t.Run("ptr", func(t *testing.T) {
    46  		b := Bool(true)
    47  		checkEncodeValueWithStandard(t, &b, nil)
    48  	})
    49  }
    50  
    51  type testBoolEncoder struct{}
    52  
    53  func (*testBoolEncoder) IsEmpty(ptr unsafe.Pointer) bool {
    54  	return *(*bool)(ptr)
    55  }
    56  
    57  func (*testBoolEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) {
    58  	if ptr == nil {
    59  		s.Null()
    60  		return
    61  	}
    62  	s.Bool(!*(*bool)(ptr))
    63  }
    64  
    65  func TestValEncoder_Bool_Kind_CustomConfig(t *testing.T) {
    66  	encCfg := NewEncoderConfig(&EncoderOption{
    67  		ValEncoders: map[reflect.Type]ValEncoder{
    68  			reflect.TypeOf(true): (*testBoolEncoder)(nil),
    69  		},
    70  	})
    71  
    72  	testStreamerWithEncoderConfig(t, encCfg, "false", func(s *Streamer) {
    73  		s.Value(true)
    74  	})
    75  	testStreamerWithEncoderConfig(t, encCfg, "true", func(s *Streamer) {
    76  		s.Value(false)
    77  	})
    78  	testStreamerWithEncoderConfig(t, encCfg, `{"B":true}`, func(s *Streamer) {
    79  		s.Value(struct {
    80  			B bool `json:",omitempty"`
    81  		}{B: false})
    82  	})
    83  	testStreamerWithEncoderConfig(t, encCfg, `{}`, func(s *Streamer) {
    84  		s.Value(struct {
    85  			B bool `json:",omitempty"`
    86  		}{B: true})
    87  	})
    88  
    89  	type Bool bool
    90  
    91  	testStreamerWithEncoderConfig(t, encCfg, "false", func(s *Streamer) {
    92  		s.Value(Bool(true))
    93  	})
    94  	testStreamerWithEncoderConfig(t, encCfg, "true", func(s *Streamer) {
    95  		s.Value(Bool(false))
    96  	})
    97  	testStreamerWithEncoderConfig(t, encCfg, `{"B":true}`, func(s *Streamer) {
    98  		s.Value(struct {
    99  			B Bool `json:",omitempty"`
   100  		}{B: false})
   101  	})
   102  	testStreamerWithEncoderConfig(t, encCfg, `{}`, func(s *Streamer) {
   103  		s.Value(struct {
   104  			B Bool `json:",omitempty"`
   105  		}{B: true})
   106  	})
   107  }
   108  
   109  func TestValEncoder_String(t *testing.T) {
   110  	f := func(t *testing.T, str string) {
   111  		checkEncodeValueWithStandard(t, str, nil)
   112  	}
   113  	t.Run("test", func(t *testing.T) {
   114  		f(t, "test")
   115  	})
   116  	t.Run("escape", func(t *testing.T) {
   117  		f(t, "\"\n\r\t\\")
   118  	})
   119  	t.Run("html escape", func(t *testing.T) {
   120  		f(t, "<>&")
   121  	})
   122  	t.Run("nil ptr", func(t *testing.T) {
   123  		checkEncodeValueWithStandard(t, (*string)(nil), nil)
   124  	})
   125  	t.Run("ptr", func(t *testing.T) {
   126  		s := "test"
   127  		checkEncodeValueWithStandard(t, &s, nil)
   128  	})
   129  	t.Run("unicode", func(t *testing.T) {
   130  		s := "\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e"
   131  		checkEncodeValueWithStandard(t, s, nil)
   132  	})
   133  	t.Run("invalid unicode", func(t *testing.T) {
   134  		s := `"invalid: \uD834x\uDD1E"`
   135  		var s2 string
   136  		err := json.Unmarshal([]byte(s), &s2)
   137  		require.NoError(t, err)
   138  		b, err := json.Marshal(s2)
   139  		require.NoError(t, err)
   140  		checkEncodeValueWithStandard(t, string(b), nil)
   141  	})
   142  }
   143  
   144  func TestValEncoder_Bool_OmitEmpty(t *testing.T) {
   145  	type st struct {
   146  		S bool `json:",omitempty"`
   147  	}
   148  	checkEncodeValueWithStandard(t, st{}, nil)
   149  	checkEncodeValueWithStandard(t, st{S: true}, nil)
   150  }
   151  
   152  func TestValEncoder_String_OmitEmpty(t *testing.T) {
   153  	type st struct {
   154  		S string `json:",omitempty"`
   155  	}
   156  	checkEncodeValueWithStandard(t, st{}, nil)
   157  	checkEncodeValueWithStandard(t, st{S: "test"}, nil)
   158  }