github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/extension_tests/decoder_test.go (about)

     1  package test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"strconv"
     8  	"testing"
     9  	"time"
    10  	"unsafe"
    11  
    12  	"github.com/bingoohuang/gg/pkg/jsoni"
    13  	"github.com/modern-go/reflect2"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func Test_customize_type_decoder(t *testing.T) {
    18  	t.Skip()
    19  	jsoni.RegisterTypeDecoderFunc("time.Time", func(ctx context.Context, ptr unsafe.Pointer, iter *jsoni.Iterator) {
    20  		t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.UTC)
    21  		if err != nil {
    22  			iter.Error = err
    23  			return
    24  		}
    25  		*((*time.Time)(ptr)) = t
    26  	})
    27  	// defer jsoni.ConfigDefault.(*frozenConfig).cleanDecoders()
    28  	val := time.Time{}
    29  	err := jsoni.Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val)
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  	year, month, day := val.Date()
    34  	if year != 2016 || month != 12 || day != 5 {
    35  		t.Fatal(val)
    36  	}
    37  }
    38  
    39  func Test_customize_byte_array_encoder(t *testing.T) {
    40  	t.Skip()
    41  	// jsoni.ConfigDefault.(*frozenConfig).cleanEncoders()
    42  	should := require.New(t)
    43  	jsoni.RegisterTypeEncoderFunc("[]uint8", func(_ context.Context, ptr unsafe.Pointer, stream *jsoni.Stream) {
    44  		t := *((*[]byte)(ptr))
    45  		stream.WriteString(string(t))
    46  	}, nil)
    47  	// defer jsoni.ConfigDefault.(*frozenConfig).cleanEncoders()
    48  	val := []byte("abc")
    49  	str, err := jsoni.MarshalToString(val)
    50  	should.Nil(err)
    51  	should.Equal(`"abc"`, str)
    52  }
    53  
    54  type CustomEncoderAttachmentTestStruct struct {
    55  	Value int32 `json:"value"`
    56  }
    57  
    58  type CustomEncoderAttachmentTestStructEncoder struct{}
    59  
    60  func (c *CustomEncoderAttachmentTestStructEncoder) Encode(_ context.Context, _ unsafe.Pointer, stream *jsoni.Stream) {
    61  	attachVal, ok := stream.Attachment.(int)
    62  	stream.WriteRaw(`"`)
    63  	stream.WriteRaw(fmt.Sprintf("%t %d", ok, attachVal))
    64  	stream.WriteRaw(`"`)
    65  }
    66  
    67  func (c *CustomEncoderAttachmentTestStructEncoder) IsEmpty(context.Context, unsafe.Pointer, bool) bool {
    68  	return false
    69  }
    70  
    71  func Test_custom_encoder_attachment(t *testing.T) {
    72  	expectedValue := 17
    73  	should := require.New(t)
    74  	buf := &bytes.Buffer{}
    75  	config := jsoni.Config{SortMapKeys: true}.Froze()
    76  	config.RegisterTypeEncoder(reflect2.TypeOf(CustomEncoderAttachmentTestStruct{}).String(),
    77  		&CustomEncoderAttachmentTestStructEncoder{})
    78  
    79  	stream := jsoni.NewStream(config, buf, 4096)
    80  	stream.Attachment = expectedValue
    81  	val := map[string]CustomEncoderAttachmentTestStruct{"a": {}}
    82  	stream.WriteVal(context.Background(), val)
    83  	stream.Flush()
    84  	should.Nil(stream.Error)
    85  	should.Equal("{\"a\":\"true 17\"}", buf.String())
    86  }
    87  
    88  func Test_customize_field_decoder(t *testing.T) {
    89  	type Tom struct {
    90  		field1 string
    91  	}
    92  	jsoni.RegisterFieldDecoderFunc("jsoni.Tom", "field1", func(ctx context.Context, ptr unsafe.Pointer, iter *jsoni.Iterator) {
    93  		*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
    94  	})
    95  	// defer jsoni.ConfigDefault.(*frozenConfig).cleanDecoders()
    96  	tom := Tom{}
    97  	err := jsoni.Unmarshal([]byte(`{"field1": 100}`), &tom)
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  }
   102  
   103  func Test_recursive_empty_interface_customization(t *testing.T) {
   104  	t.Skip()
   105  	var obj interface{}
   106  	jsoni.RegisterTypeDecoderFunc("interface {}", func(ctx context.Context, ptr unsafe.Pointer, iter *jsoni.Iterator) {
   107  		switch iter.WhatIsNext() {
   108  		case jsoni.NumberValue:
   109  			*(*interface{})(ptr) = iter.ReadInt64()
   110  		default:
   111  			*(*interface{})(ptr) = iter.Read(ctx)
   112  		}
   113  	})
   114  	should := require.New(t)
   115  	jsoni.Unmarshal([]byte("[100]"), &obj)
   116  	should.Equal([]interface{}{int64(100)}, obj)
   117  }
   118  
   119  type MyInterface interface {
   120  	Hello() string
   121  }
   122  
   123  type MyString string
   124  
   125  func (ms MyString) Hello() string {
   126  	return string(ms)
   127  }
   128  
   129  func Test_read_custom_interface(t *testing.T) {
   130  	t.Skip()
   131  	should := require.New(t)
   132  	var val MyInterface
   133  	jsoni.RegisterTypeDecoderFunc("jsoni.MyInterface", func(ctx context.Context, ptr unsafe.Pointer, iter *jsoni.Iterator) {
   134  		*((*MyInterface)(ptr)) = MyString(iter.ReadString())
   135  	})
   136  	err := jsoni.UnmarshalFromString(`"hello"`, &val)
   137  	should.Nil(err)
   138  	should.Equal("hello", val.Hello())
   139  }
   140  
   141  const flow1 = `
   142  {"A":"hello"}
   143  {"A":"hello"}
   144  {"A":"hello"}
   145  {"A":"hello"}
   146  {"A":"hello"}`
   147  
   148  const flow2 = `
   149  {"A":"hello"}
   150  {"A":"hello"}
   151  {"A":"hello"}
   152  {"A":"hello"}
   153  {"A":"hello"}
   154  `
   155  
   156  type (
   157  	Type1 struct {
   158  		A string
   159  	}
   160  
   161  	Type2 struct {
   162  		A string
   163  	}
   164  )
   165  
   166  func (t *Type2) UnmarshalJSON(data []byte) error {
   167  	return nil
   168  }
   169  
   170  func (t *Type2) MarshalJSON() ([]byte, error) {
   171  	return nil, nil
   172  }
   173  
   174  func TestType1NoFinalLF(t *testing.T) {
   175  	reader := bytes.NewReader([]byte(flow1))
   176  	dec := jsoni.NewDecoder(reader)
   177  	ctx := context.Background()
   178  	i := 0
   179  	for dec.More() {
   180  		data := &Type1{}
   181  		if err := dec.Decode(ctx, data); err != nil {
   182  			t.Errorf("at %v got %v", i, err)
   183  		}
   184  		i++
   185  	}
   186  }
   187  
   188  func TestType1FinalLF(t *testing.T) {
   189  	reader := bytes.NewReader([]byte(flow2))
   190  	dec := jsoni.NewDecoder(reader)
   191  
   192  	i := 0
   193  	ctx := context.Background()
   194  	for dec.More() {
   195  		data := &Type1{}
   196  		if err := dec.Decode(ctx, data); err != nil {
   197  			t.Errorf("at %v got %v", i, err)
   198  		}
   199  		i++
   200  	}
   201  }
   202  
   203  func TestType2NoFinalLF(t *testing.T) {
   204  	reader := bytes.NewReader([]byte(flow1))
   205  	dec := jsoni.NewDecoder(reader)
   206  	ctx := context.Background()
   207  	i := 0
   208  	for dec.More() {
   209  		data := &Type2{}
   210  		if err := dec.Decode(ctx, data); err != nil {
   211  			t.Errorf("at %v got %v", i, err)
   212  		}
   213  		i++
   214  	}
   215  }
   216  
   217  func TestType2FinalLF(t *testing.T) {
   218  	reader := bytes.NewReader([]byte(flow2))
   219  	dec := jsoni.NewDecoder(reader)
   220  	ctx := context.Background()
   221  	i := 0
   222  	for dec.More() {
   223  		data := &Type2{}
   224  		if err := dec.Decode(ctx, data); err != nil {
   225  			t.Errorf("at %v got %v", i, err)
   226  		}
   227  		i++
   228  	}
   229  }