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 }