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

     1  package jzon
     2  
     3  import (
     4  	"encoding"
     5  	"errors"
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestValEncoder_TextMarshaler_ChainError(t *testing.T) {
    13  	t.Run("direct", func(t *testing.T) {
    14  		testStreamerChainError(t, func(s *Streamer) {
    15  			(*textMarshalerEncoder)(nil).Encode(nil, s, nil)
    16  		})
    17  	})
    18  	t.Run("dynamic", func(t *testing.T) {
    19  		testStreamerChainError(t, func(s *Streamer) {
    20  			(*dynamicTextMarshalerEncoder)(nil).Encode(nil, s, nil)
    21  		})
    22  	})
    23  }
    24  
    25  type testTextMarshaler struct {
    26  	data string
    27  	err  error
    28  }
    29  
    30  func (m testTextMarshaler) MarshalText() ([]byte, error) {
    31  	return []byte(m.data), m.err
    32  }
    33  
    34  type testTextMarshaler2 struct {
    35  	data string
    36  	err  error
    37  }
    38  
    39  func (m *testTextMarshaler2) MarshalText() ([]byte, error) {
    40  	if m == nil {
    41  		return []byte(`is_null`), nil
    42  	}
    43  	return []byte(m.data), m.err
    44  }
    45  
    46  func TestValEncoder_TextMarshaler(t *testing.T) {
    47  	f := func(t *testing.T, m encoding.TextMarshaler, err error) {
    48  		checkEncodeValueWithStandard(t, m, err)
    49  	}
    50  	t.Run("non pointer receiver", func(t *testing.T) {
    51  		t.Run("non pointer", func(t *testing.T) {
    52  			f(t, testTextMarshaler{
    53  				data: `{"a":1}`,
    54  			}, nil)
    55  		})
    56  		t.Run("non pointer error", func(t *testing.T) {
    57  			e := errors.New("test")
    58  			f(t, testTextMarshaler{
    59  				data: `{"a":1}`,
    60  				err:  e,
    61  			}, e)
    62  		})
    63  		t.Run("pointer", func(t *testing.T) {
    64  			f(t, &testTextMarshaler{
    65  				data: `{"a":2}`,
    66  			}, nil)
    67  		})
    68  		t.Run("pointer error", func(t *testing.T) {
    69  			e := errors.New("test")
    70  			f(t, &testTextMarshaler{
    71  				data: `{"a":2}`,
    72  				err:  e,
    73  			}, e)
    74  		})
    75  		t.Run("nil pointer", func(t *testing.T) {
    76  			f(t, (*testTextMarshaler)(nil), nil)
    77  		})
    78  	})
    79  	t.Run("pointer receiver", func(t *testing.T) {
    80  		t.Run("pointer", func(t *testing.T) {
    81  			f(t, &testTextMarshaler2{
    82  				data: `{"b":1}`,
    83  			}, nil)
    84  		})
    85  		t.Run("pointer error", func(t *testing.T) {
    86  			e := errors.New("test")
    87  			f(t, &testTextMarshaler2{
    88  				data: `{"b":1}`,
    89  				err:  e,
    90  			}, e)
    91  		})
    92  		t.Run("nil pointer", func(t *testing.T) {
    93  			f(t, (*testTextMarshaler2)(nil), nil)
    94  		})
    95  	})
    96  }
    97  
    98  func TestValEncoder_DynamicTextMarshaler(t *testing.T) {
    99  	t.Run("marshaler nil", func(t *testing.T) {
   100  		// TODO: This test should be automatically fixed in the future golang version
   101  		v := "go1.13.15"
   102  		if goVersion.LessEqual(v) {
   103  			var i encoding.TextMarshaler
   104  			b, err := Marshal(&i)
   105  			require.NoError(t, err)
   106  			require.Equal(t, "null", string(b))
   107  		} else {
   108  			var i encoding.TextMarshaler
   109  			checkEncodeValueWithStandard(t, &i, nil)
   110  		}
   111  	})
   112  	t.Run("marshaler error", func(t *testing.T) {
   113  		e := errors.New("test")
   114  		var i encoding.TextMarshaler = testTextMarshaler{
   115  			data: `"test"`,
   116  			err:  e,
   117  		}
   118  		checkEncodeValueWithStandard(t, &i, e)
   119  	})
   120  	t.Run("marshaler", func(t *testing.T) {
   121  		var i encoding.TextMarshaler = testTextMarshaler{
   122  			data: `"test"`,
   123  		}
   124  		checkEncodeValueWithStandard(t, &i, nil)
   125  	})
   126  	t.Run("marshaler 2", func(t *testing.T) {
   127  		var i encoding.TextMarshaler = &testTextMarshaler{
   128  			data: `"test 2"`,
   129  		}
   130  		checkEncodeValueWithStandard(t, &i, nil)
   131  	})
   132  }
   133  
   134  type testDirectTextMarshaler map[int]int
   135  
   136  func (m testDirectTextMarshaler) MarshalText() ([]byte, error) {
   137  	s := fmt.Sprintf("%d", len(m))
   138  	return []byte(s), nil
   139  }
   140  
   141  func TestValEncoder_TextMarshaler_Direct(t *testing.T) {
   142  	t.Run("value", func(t *testing.T) {
   143  		t.Run("nil", func(t *testing.T) {
   144  			checkEncodeValueWithStandard(t, testDirectTextMarshaler(nil), nil)
   145  		})
   146  		t.Run("non nil", func(t *testing.T) {
   147  			checkEncodeValueWithStandard(t, testDirectTextMarshaler{
   148  				1: 2,
   149  			}, nil)
   150  		})
   151  	})
   152  	t.Run("pointer", func(t *testing.T) {
   153  		t.Run("nil", func(t *testing.T) {
   154  			checkEncodeValueWithStandard(t, (*testDirectTextMarshaler)(nil), nil)
   155  		})
   156  		t.Run("non nil", func(t *testing.T) {
   157  			var m testDirectTextMarshaler
   158  			checkEncodeValueWithStandard(t, &m, nil)
   159  		})
   160  		t.Run("non nil 2", func(t *testing.T) {
   161  			checkEncodeValueWithStandard(t, &testDirectTextMarshaler{
   162  				1: 2,
   163  			}, nil)
   164  		})
   165  	})
   166  	t.Run("struct member", func(t *testing.T) {
   167  		type st struct {
   168  			A testDirectTextMarshaler
   169  		}
   170  		checkEncodeValueWithStandard(t, &st{}, nil)
   171  	})
   172  }
   173  
   174  func TestValEncoder_TextMarshaler_OmitEmpty(t *testing.T) {
   175  	t.Run("text marshaler", func(t *testing.T) {
   176  		type st struct {
   177  			A testTextMarshaler `json:",omitempty"`
   178  		}
   179  		checkEncodeValueWithStandard(t, st{
   180  			A: testTextMarshaler{
   181  				data: "true",
   182  			},
   183  		}, nil)
   184  	})
   185  	t.Run("direct text marshaler", func(t *testing.T) {
   186  		type st struct {
   187  			A testDirectTextMarshaler `json:",omitempty"`
   188  		}
   189  		t.Run("nil", func(t *testing.T) {
   190  			checkEncodeValueWithStandard(t, st{}, nil)
   191  		})
   192  		t.Run("zero", func(t *testing.T) {
   193  			checkEncodeValueWithStandard(t, st{
   194  				A: testDirectTextMarshaler{},
   195  			}, nil)
   196  		})
   197  		t.Run("non zero", func(t *testing.T) {
   198  			checkEncodeValueWithStandard(t, st{
   199  				A: testDirectTextMarshaler{1: 2},
   200  			}, nil)
   201  		})
   202  	})
   203  	t.Run("pointer text marshaler", func(t *testing.T) {
   204  		type st struct {
   205  			A testTextMarshaler2 `json:",omitempty"`
   206  		}
   207  		checkEncodeValueWithStandard(t, &st{
   208  			A: testTextMarshaler2{
   209  				data: "true",
   210  			},
   211  		}, nil)
   212  	})
   213  	t.Run("dynamic text marshaler", func(t *testing.T) {
   214  		type st struct {
   215  			A encoding.TextMarshaler `json:",omitempty"`
   216  		}
   217  		t.Run("nil", func(t *testing.T) {
   218  			checkEncodeValueWithStandard(t, st{}, nil)
   219  		})
   220  		t.Run("nil pointer", func(t *testing.T) {
   221  			checkEncodeValueWithStandard(t, st{
   222  				A: (*testTextMarshaler2)(nil),
   223  			}, nil)
   224  		})
   225  	})
   226  }