gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

encode_sqlnull_test.go (33572B)


      1 package gojay
      2 
      3 import (
      4 	"database/sql"
      5 	"strings"
      6 	"testing"
      7 
      8 	"github.com/stretchr/testify/assert"
      9 )
     10 
     11 // Null String
     12 func TestEncoceSQLNullString(t *testing.T) {
     13 	testCases := []struct {
     14 		name           string
     15 		sqlNullString  sql.NullString
     16 		expectedResult string
     17 		err            bool
     18 	}{
     19 		{
     20 			name: "it should encode a null string",
     21 			sqlNullString: sql.NullString{
     22 				String: "foo bar",
     23 			},
     24 			expectedResult: `"foo bar"`,
     25 		},
     26 		{
     27 			name: "it should return an err as the string is invalid",
     28 			sqlNullString: sql.NullString{
     29 				String: "foo \t bar",
     30 			},
     31 			expectedResult: `"foo \t bar"`,
     32 		},
     33 	}
     34 
     35 	for _, testCase := range testCases {
     36 		t.Run(testCase.name, func(t *testing.T) {
     37 			var b strings.Builder
     38 			enc := NewEncoder(&b)
     39 			err := enc.EncodeSQLNullString(&testCase.sqlNullString)
     40 			if testCase.err {
     41 				assert.NotNil(t, err)
     42 			} else {
     43 				assert.Nil(t, err)
     44 				assert.Equal(t, testCase.expectedResult, b.String())
     45 			}
     46 		})
     47 	}
     48 
     49 	t.Run(
     50 		"should panic as the encoder is pooled",
     51 		func(t *testing.T) {
     52 			builder := &strings.Builder{}
     53 			enc := NewEncoder(builder)
     54 			enc.isPooled = 1
     55 			defer func() {
     56 				err := recover()
     57 				assert.NotNil(t, err, "err should not be nil")
     58 				assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
     59 			}()
     60 			_ = enc.EncodeSQLNullString(&sql.NullString{})
     61 			assert.True(t, false, "should not be called as encoder should have panicked")
     62 		},
     63 	)
     64 
     65 	t.Run(
     66 		"should return an error as the writer encounters an error",
     67 		func(t *testing.T) {
     68 			builder := TestWriterError("")
     69 			enc := NewEncoder(builder)
     70 			err := enc.EncodeSQLNullString(&sql.NullString{})
     71 			assert.NotNil(t, err)
     72 		},
     73 	)
     74 }
     75 
     76 func TestAddSQLNullStringKey(t *testing.T) {
     77 	t.Run(
     78 		"AddSQLNullStringKey",
     79 		func(t *testing.T) {
     80 			testCases := []struct {
     81 				name           string
     82 				sqlNullString  sql.NullString
     83 				baseJSON       string
     84 				expectedResult string
     85 				err            bool
     86 			}{
     87 				{
     88 					name: "it should encode a null string",
     89 					sqlNullString: sql.NullString{
     90 						String: "foo bar",
     91 					},
     92 					baseJSON:       "{",
     93 					expectedResult: `{"foo":"foo bar"`,
     94 				},
     95 				{
     96 					name: "it should encode a null string",
     97 					sqlNullString: sql.NullString{
     98 						String: "foo \t bar",
     99 					},
    100 					baseJSON:       "{",
    101 					expectedResult: `{"foo":"foo \t bar"`,
    102 				},
    103 				{
    104 					name: "it should encode a null string",
    105 					sqlNullString: sql.NullString{
    106 						String: "foo \t bar",
    107 					},
    108 					baseJSON:       "{",
    109 					expectedResult: `{"foo":"foo \t bar"`,
    110 				},
    111 			}
    112 
    113 			for _, testCase := range testCases {
    114 				t.Run(testCase.name, func(t *testing.T) {
    115 					var b strings.Builder
    116 					enc := NewEncoder(&b)
    117 					enc.writeString(testCase.baseJSON)
    118 					enc.AddSQLNullStringKey("foo", &testCase.sqlNullString)
    119 					enc.Write()
    120 					assert.Equal(t, testCase.expectedResult, b.String())
    121 
    122 					var b2 strings.Builder
    123 					enc = NewEncoder(&b2)
    124 					enc.writeString(testCase.baseJSON)
    125 					enc.SQLNullStringKey("foo", &testCase.sqlNullString)
    126 					enc.Write()
    127 					assert.Equal(t, testCase.expectedResult, b2.String())
    128 				})
    129 			}
    130 		},
    131 	)
    132 	t.Run(
    133 		"AddSQLNullStringKeyOmitEmpty, is should encode a sql.NullString",
    134 		func(t *testing.T) {
    135 			testCases := []struct {
    136 				name           string
    137 				sqlNullString  sql.NullString
    138 				baseJSON       string
    139 				expectedResult string
    140 				err            bool
    141 			}{
    142 				{
    143 					name: "it should encode a null string",
    144 					sqlNullString: sql.NullString{
    145 						String: "foo bar",
    146 						Valid:  true,
    147 					},
    148 					baseJSON:       "{",
    149 					expectedResult: `{"foo":"foo bar"`,
    150 				},
    151 				{
    152 					name: "it should not encode anything as null string is invalid",
    153 					sqlNullString: sql.NullString{
    154 						String: "foo \t bar",
    155 						Valid:  false,
    156 					},
    157 					baseJSON:       "{",
    158 					expectedResult: `{`,
    159 				},
    160 			}
    161 
    162 			for _, testCase := range testCases {
    163 				t.Run(testCase.name, func(t *testing.T) {
    164 					var b strings.Builder
    165 					enc := NewEncoder(&b)
    166 					enc.writeString(testCase.baseJSON)
    167 					enc.AddSQLNullStringKeyOmitEmpty("foo", &testCase.sqlNullString)
    168 					enc.Write()
    169 					assert.Equal(t, testCase.expectedResult, b.String())
    170 
    171 					var b2 strings.Builder
    172 					enc = NewEncoder(&b2)
    173 					enc.writeString(testCase.baseJSON)
    174 					enc.SQLNullStringKeyOmitEmpty("foo", &testCase.sqlNullString)
    175 					enc.Write()
    176 					assert.Equal(t, testCase.expectedResult, b2.String())
    177 				})
    178 			}
    179 		},
    180 	)
    181 }
    182 
    183 func TestAddSQLNullString(t *testing.T) {
    184 	t.Run(
    185 		"AddSQLNullString",
    186 		func(t *testing.T) {
    187 			testCases := []struct {
    188 				name           string
    189 				sqlNullString  sql.NullString
    190 				baseJSON       string
    191 				expectedResult string
    192 				err            bool
    193 			}{
    194 				{
    195 					name: "it should encode a null string",
    196 					sqlNullString: sql.NullString{
    197 						String: "foo bar",
    198 					},
    199 					baseJSON:       "[",
    200 					expectedResult: `["foo bar"`,
    201 				},
    202 				{
    203 					name: "it should encode a null string",
    204 					sqlNullString: sql.NullString{
    205 						String: "foo \t bar",
    206 					},
    207 					baseJSON:       "[",
    208 					expectedResult: `["foo \t bar"`,
    209 				},
    210 				{
    211 					name: "it should encode a null string",
    212 					sqlNullString: sql.NullString{
    213 						String: "foo \t bar",
    214 					},
    215 					baseJSON:       "[",
    216 					expectedResult: `["foo \t bar"`,
    217 				},
    218 			}
    219 
    220 			for _, testCase := range testCases {
    221 				t.Run(testCase.name, func(t *testing.T) {
    222 					var b strings.Builder
    223 					enc := NewEncoder(&b)
    224 					enc.writeString(testCase.baseJSON)
    225 					enc.AddSQLNullString(&testCase.sqlNullString)
    226 					enc.Write()
    227 					assert.Equal(t, testCase.expectedResult, b.String())
    228 
    229 					var b2 strings.Builder
    230 					enc = NewEncoder(&b2)
    231 					enc.writeString(testCase.baseJSON)
    232 					enc.SQLNullString(&testCase.sqlNullString)
    233 					enc.Write()
    234 					assert.Equal(t, testCase.expectedResult, b2.String())
    235 				})
    236 			}
    237 		},
    238 	)
    239 	t.Run(
    240 		"AddSQLNullStringKeyOmitEmpty, is should encode a sql.NullString",
    241 		func(t *testing.T) {
    242 			testCases := []struct {
    243 				name           string
    244 				sqlNullString  sql.NullString
    245 				baseJSON       string
    246 				expectedResult string
    247 				err            bool
    248 			}{
    249 				{
    250 					name: "it should encode a null string",
    251 					sqlNullString: sql.NullString{
    252 						String: "foo bar",
    253 						Valid:  true,
    254 					},
    255 					baseJSON:       "[",
    256 					expectedResult: `["foo bar"`,
    257 				},
    258 				{
    259 					name: "it should not encode anything as null string is invalid",
    260 					sqlNullString: sql.NullString{
    261 						String: "foo \t bar",
    262 						Valid:  false,
    263 					},
    264 					baseJSON:       "[",
    265 					expectedResult: `[`,
    266 				},
    267 			}
    268 
    269 			for _, testCase := range testCases {
    270 				t.Run(testCase.name, func(t *testing.T) {
    271 					var b strings.Builder
    272 					enc := NewEncoder(&b)
    273 					enc.writeString(testCase.baseJSON)
    274 					enc.AddSQLNullStringOmitEmpty(&testCase.sqlNullString)
    275 					enc.Write()
    276 					assert.Equal(t, testCase.expectedResult, b.String())
    277 
    278 					var b2 strings.Builder
    279 					enc = NewEncoder(&b2)
    280 					enc.writeString(testCase.baseJSON)
    281 					enc.SQLNullStringOmitEmpty(&testCase.sqlNullString)
    282 					enc.Write()
    283 					assert.Equal(t, testCase.expectedResult, b2.String())
    284 				})
    285 			}
    286 		},
    287 	)
    288 }
    289 
    290 // NullInt64
    291 func TestEncoceSQLNullInt64(t *testing.T) {
    292 	testCases := []struct {
    293 		name           string
    294 		sqlNullInt64   sql.NullInt64
    295 		expectedResult string
    296 		err            bool
    297 	}{
    298 		{
    299 			name: "it should encode a null string",
    300 			sqlNullInt64: sql.NullInt64{
    301 				Int64: int64(1),
    302 			},
    303 			expectedResult: `1`,
    304 		},
    305 		{
    306 			name: "it should return an err as the string is invalid",
    307 			sqlNullInt64: sql.NullInt64{
    308 				Int64: int64(2),
    309 			},
    310 			expectedResult: `2`,
    311 		},
    312 	}
    313 
    314 	for _, testCase := range testCases {
    315 		t.Run(testCase.name, func(t *testing.T) {
    316 			var b strings.Builder
    317 			enc := NewEncoder(&b)
    318 			err := enc.EncodeSQLNullInt64(&testCase.sqlNullInt64)
    319 			if testCase.err {
    320 				assert.NotNil(t, err)
    321 			} else {
    322 				assert.Nil(t, err)
    323 				assert.Equal(t, testCase.expectedResult, b.String())
    324 			}
    325 		})
    326 	}
    327 	t.Run(
    328 		"should panic as the encoder is pooled",
    329 		func(t *testing.T) {
    330 			builder := &strings.Builder{}
    331 			enc := NewEncoder(builder)
    332 			enc.isPooled = 1
    333 			defer func() {
    334 				err := recover()
    335 				assert.NotNil(t, err, "err should not be nil")
    336 				assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
    337 			}()
    338 			_ = enc.EncodeSQLNullInt64(&sql.NullInt64{})
    339 			assert.True(t, false, "should not be called as encoder should have panicked")
    340 		},
    341 	)
    342 	t.Run(
    343 		"should return an error as the writer encounters an error",
    344 		func(t *testing.T) {
    345 			builder := TestWriterError("")
    346 			enc := NewEncoder(builder)
    347 			err := enc.EncodeSQLNullInt64(&sql.NullInt64{})
    348 			assert.NotNil(t, err)
    349 		},
    350 	)
    351 }
    352 
    353 func TestAddSQLNullInt64Key(t *testing.T) {
    354 	t.Run(
    355 		"AddSQLNullInt64Key",
    356 		func(t *testing.T) {
    357 			testCases := []struct {
    358 				name           string
    359 				sqlNullInt64   sql.NullInt64
    360 				baseJSON       string
    361 				expectedResult string
    362 				err            bool
    363 			}{
    364 				{
    365 					name: "it should encode a null string",
    366 					sqlNullInt64: sql.NullInt64{
    367 						Int64: 1,
    368 					},
    369 					baseJSON:       "{",
    370 					expectedResult: `{"foo":1`,
    371 				},
    372 				{
    373 					name: "it should encode a null string",
    374 					sqlNullInt64: sql.NullInt64{
    375 						Int64: 2,
    376 					},
    377 					baseJSON:       "{",
    378 					expectedResult: `{"foo":2`,
    379 				},
    380 				{
    381 					name: "it should encode a null string",
    382 					sqlNullInt64: sql.NullInt64{
    383 						Int64: 2,
    384 					},
    385 					baseJSON:       "{",
    386 					expectedResult: `{"foo":2`,
    387 				},
    388 			}
    389 
    390 			for _, testCase := range testCases {
    391 				t.Run(testCase.name, func(t *testing.T) {
    392 					var b strings.Builder
    393 					enc := NewEncoder(&b)
    394 					enc.writeString(testCase.baseJSON)
    395 					enc.AddSQLNullInt64Key("foo", &testCase.sqlNullInt64)
    396 					enc.Write()
    397 					assert.Equal(t, testCase.expectedResult, b.String())
    398 
    399 					var b2 strings.Builder
    400 					enc = NewEncoder(&b2)
    401 					enc.writeString(testCase.baseJSON)
    402 					enc.SQLNullInt64Key("foo", &testCase.sqlNullInt64)
    403 					enc.Write()
    404 					assert.Equal(t, testCase.expectedResult, b2.String())
    405 				})
    406 			}
    407 		},
    408 	)
    409 	t.Run(
    410 		"AddSQLNullInt64KeyOmitEmpty, is should encode a sql.NullInt64",
    411 		func(t *testing.T) {
    412 			testCases := []struct {
    413 				name           string
    414 				sqlNullInt64   sql.NullInt64
    415 				baseJSON       string
    416 				expectedResult string
    417 				err            bool
    418 			}{
    419 				{
    420 					name: "it should encode a null string",
    421 					sqlNullInt64: sql.NullInt64{
    422 						Int64: 1,
    423 						Valid: true,
    424 					},
    425 					baseJSON:       "{",
    426 					expectedResult: `{"foo":1`,
    427 				},
    428 				{
    429 					name: "it should not encode anything as null string is invalid",
    430 					sqlNullInt64: sql.NullInt64{
    431 						Int64: 2,
    432 						Valid: false,
    433 					},
    434 					baseJSON:       "{",
    435 					expectedResult: `{`,
    436 				},
    437 			}
    438 
    439 			for _, testCase := range testCases {
    440 				t.Run(testCase.name, func(t *testing.T) {
    441 					var b strings.Builder
    442 					enc := NewEncoder(&b)
    443 					enc.writeString(testCase.baseJSON)
    444 					enc.AddSQLNullInt64KeyOmitEmpty("foo", &testCase.sqlNullInt64)
    445 					enc.Write()
    446 					assert.Equal(t, testCase.expectedResult, b.String())
    447 
    448 					var b2 strings.Builder
    449 					enc = NewEncoder(&b2)
    450 					enc.writeString(testCase.baseJSON)
    451 					enc.SQLNullInt64KeyOmitEmpty("foo", &testCase.sqlNullInt64)
    452 					enc.Write()
    453 					assert.Equal(t, testCase.expectedResult, b2.String())
    454 				})
    455 			}
    456 		},
    457 	)
    458 }
    459 
    460 func TestAddSQLNullInt64(t *testing.T) {
    461 	t.Run(
    462 		"AddSQLNullInt64",
    463 		func(t *testing.T) {
    464 			testCases := []struct {
    465 				name           string
    466 				sqlNullInt64   sql.NullInt64
    467 				baseJSON       string
    468 				expectedResult string
    469 				err            bool
    470 			}{
    471 				{
    472 					name: "it should encode a null string",
    473 					sqlNullInt64: sql.NullInt64{
    474 						Int64: 1,
    475 					},
    476 					baseJSON:       "[",
    477 					expectedResult: `[1`,
    478 				},
    479 				{
    480 					name: "it should encode a null string",
    481 					sqlNullInt64: sql.NullInt64{
    482 						Int64: 2,
    483 					},
    484 					baseJSON:       "[",
    485 					expectedResult: `[2`,
    486 				},
    487 				{
    488 					name: "it should encode a null string",
    489 					sqlNullInt64: sql.NullInt64{
    490 						Int64: 2,
    491 					},
    492 					baseJSON:       "[",
    493 					expectedResult: `[2`,
    494 				},
    495 			}
    496 
    497 			for _, testCase := range testCases {
    498 				t.Run(testCase.name, func(t *testing.T) {
    499 					var b strings.Builder
    500 					enc := NewEncoder(&b)
    501 					enc.writeString(testCase.baseJSON)
    502 					enc.AddSQLNullInt64(&testCase.sqlNullInt64)
    503 					enc.Write()
    504 					assert.Equal(t, testCase.expectedResult, b.String())
    505 
    506 					var b2 strings.Builder
    507 					enc = NewEncoder(&b2)
    508 					enc.writeString(testCase.baseJSON)
    509 					enc.SQLNullInt64(&testCase.sqlNullInt64)
    510 					enc.Write()
    511 					assert.Equal(t, testCase.expectedResult, b2.String())
    512 				})
    513 			}
    514 		},
    515 	)
    516 	t.Run(
    517 		"AddSQLNullInt64KeyOmitEmpty, is should encode a sql.NullInt64",
    518 		func(t *testing.T) {
    519 			testCases := []struct {
    520 				name           string
    521 				sqlNullInt64   sql.NullInt64
    522 				baseJSON       string
    523 				expectedResult string
    524 				err            bool
    525 			}{
    526 				{
    527 					name: "it should encode a null string",
    528 					sqlNullInt64: sql.NullInt64{
    529 						Int64: 2,
    530 						Valid: true,
    531 					},
    532 					baseJSON:       "[",
    533 					expectedResult: `[2`,
    534 				},
    535 				{
    536 					name: "it should not encode anything as null string is invalid",
    537 					sqlNullInt64: sql.NullInt64{
    538 						Int64: 2,
    539 						Valid: false,
    540 					},
    541 					baseJSON:       "[",
    542 					expectedResult: `[`,
    543 				},
    544 			}
    545 
    546 			for _, testCase := range testCases {
    547 				t.Run(testCase.name, func(t *testing.T) {
    548 					var b strings.Builder
    549 					enc := NewEncoder(&b)
    550 					enc.writeString(testCase.baseJSON)
    551 					enc.AddSQLNullInt64OmitEmpty(&testCase.sqlNullInt64)
    552 					enc.Write()
    553 					assert.Equal(t, testCase.expectedResult, b.String())
    554 
    555 					var b2 strings.Builder
    556 					enc = NewEncoder(&b2)
    557 					enc.writeString(testCase.baseJSON)
    558 					enc.SQLNullInt64OmitEmpty(&testCase.sqlNullInt64)
    559 					enc.Write()
    560 					assert.Equal(t, testCase.expectedResult, b2.String())
    561 				})
    562 			}
    563 		},
    564 	)
    565 }
    566 
    567 // NullFloat64
    568 func TestEncoceSQLNullFloat64(t *testing.T) {
    569 	testCases := []struct {
    570 		name           string
    571 		sqlNullFloat64 sql.NullFloat64
    572 		expectedResult string
    573 		err            bool
    574 	}{
    575 		{
    576 			name: "it should encode a null string",
    577 			sqlNullFloat64: sql.NullFloat64{
    578 				Float64: float64(1),
    579 			},
    580 			expectedResult: `1`,
    581 		},
    582 		{
    583 			name: "it should return an err as the string is invalid",
    584 			sqlNullFloat64: sql.NullFloat64{
    585 				Float64: float64(2),
    586 			},
    587 			expectedResult: `2`,
    588 		},
    589 	}
    590 
    591 	for _, testCase := range testCases {
    592 		t.Run(testCase.name, func(t *testing.T) {
    593 			var b strings.Builder
    594 			enc := NewEncoder(&b)
    595 			err := enc.EncodeSQLNullFloat64(&testCase.sqlNullFloat64)
    596 			if testCase.err {
    597 				assert.NotNil(t, err)
    598 			} else {
    599 				assert.Nil(t, err)
    600 				assert.Equal(t, testCase.expectedResult, b.String())
    601 			}
    602 		})
    603 	}
    604 	t.Run(
    605 		"should panic as the encoder is pooled",
    606 		func(t *testing.T) {
    607 			builder := &strings.Builder{}
    608 			enc := NewEncoder(builder)
    609 			enc.isPooled = 1
    610 			defer func() {
    611 				err := recover()
    612 				assert.NotNil(t, err, "err should not be nil")
    613 				assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
    614 			}()
    615 			_ = enc.EncodeSQLNullFloat64(&sql.NullFloat64{})
    616 			assert.True(t, false, "should not be called as encoder should have panicked")
    617 		},
    618 	)
    619 
    620 	t.Run(
    621 		"should return an error as the writer encounters an error",
    622 		func(t *testing.T) {
    623 			builder := TestWriterError("")
    624 			enc := NewEncoder(builder)
    625 			err := enc.EncodeSQLNullFloat64(&sql.NullFloat64{})
    626 			assert.NotNil(t, err)
    627 		},
    628 	)
    629 }
    630 
    631 func TestAddSQLNullFloat64Key(t *testing.T) {
    632 	t.Run(
    633 		"AddSQLNullFloat64Key",
    634 		func(t *testing.T) {
    635 			testCases := []struct {
    636 				name           string
    637 				sqlNullFloat64 sql.NullFloat64
    638 				baseJSON       string
    639 				expectedResult string
    640 				err            bool
    641 			}{
    642 				{
    643 					name: "it should encode a null string",
    644 					sqlNullFloat64: sql.NullFloat64{
    645 						Float64: 1,
    646 					},
    647 					baseJSON:       "{",
    648 					expectedResult: `{"foo":1`,
    649 				},
    650 				{
    651 					name: "it should encode a null string",
    652 					sqlNullFloat64: sql.NullFloat64{
    653 						Float64: 2,
    654 					},
    655 					baseJSON:       "{",
    656 					expectedResult: `{"foo":2`,
    657 				},
    658 				{
    659 					name: "it should encode a null string",
    660 					sqlNullFloat64: sql.NullFloat64{
    661 						Float64: 2,
    662 					},
    663 					baseJSON:       "{",
    664 					expectedResult: `{"foo":2`,
    665 				},
    666 			}
    667 
    668 			for _, testCase := range testCases {
    669 				t.Run(testCase.name, func(t *testing.T) {
    670 					var b strings.Builder
    671 					enc := NewEncoder(&b)
    672 					enc.writeString(testCase.baseJSON)
    673 					enc.AddSQLNullFloat64Key("foo", &testCase.sqlNullFloat64)
    674 					enc.Write()
    675 					assert.Equal(t, testCase.expectedResult, b.String())
    676 
    677 					var b2 strings.Builder
    678 					enc = NewEncoder(&b2)
    679 					enc.writeString(testCase.baseJSON)
    680 					enc.SQLNullFloat64Key("foo", &testCase.sqlNullFloat64)
    681 					enc.Write()
    682 					assert.Equal(t, testCase.expectedResult, b2.String())
    683 				})
    684 			}
    685 		},
    686 	)
    687 	t.Run(
    688 		"AddSQLNullFloat64KeyOmitEmpty, is should encode a sql.NullFloat64",
    689 		func(t *testing.T) {
    690 			testCases := []struct {
    691 				name           string
    692 				sqlNullFloat64 sql.NullFloat64
    693 				baseJSON       string
    694 				expectedResult string
    695 				err            bool
    696 			}{
    697 				{
    698 					name: "it should encode a null string",
    699 					sqlNullFloat64: sql.NullFloat64{
    700 						Float64: 1,
    701 						Valid:   true,
    702 					},
    703 					baseJSON:       "{",
    704 					expectedResult: `{"foo":1`,
    705 				},
    706 				{
    707 					name: "it should not encode anything as null string is invalid",
    708 					sqlNullFloat64: sql.NullFloat64{
    709 						Float64: 2,
    710 						Valid:   false,
    711 					},
    712 					baseJSON:       "{",
    713 					expectedResult: `{`,
    714 				},
    715 			}
    716 
    717 			for _, testCase := range testCases {
    718 				t.Run(testCase.name, func(t *testing.T) {
    719 					var b strings.Builder
    720 					enc := NewEncoder(&b)
    721 					enc.writeString(testCase.baseJSON)
    722 					enc.AddSQLNullFloat64KeyOmitEmpty("foo", &testCase.sqlNullFloat64)
    723 					enc.Write()
    724 					assert.Equal(t, testCase.expectedResult, b.String())
    725 
    726 					var b2 strings.Builder
    727 					enc = NewEncoder(&b2)
    728 					enc.writeString(testCase.baseJSON)
    729 					enc.SQLNullFloat64KeyOmitEmpty("foo", &testCase.sqlNullFloat64)
    730 					enc.Write()
    731 					assert.Equal(t, testCase.expectedResult, b2.String())
    732 				})
    733 			}
    734 		},
    735 	)
    736 }
    737 
    738 func TestAddSQLNullFloat64(t *testing.T) {
    739 	t.Run(
    740 		"AddSQLNullFloat64",
    741 		func(t *testing.T) {
    742 			testCases := []struct {
    743 				name           string
    744 				sqlNullFloat64 sql.NullFloat64
    745 				baseJSON       string
    746 				expectedResult string
    747 				err            bool
    748 			}{
    749 				{
    750 					name: "it should encode a null string",
    751 					sqlNullFloat64: sql.NullFloat64{
    752 						Float64: 1,
    753 					},
    754 					baseJSON:       "[",
    755 					expectedResult: `[1`,
    756 				},
    757 				{
    758 					name: "it should encode a null string",
    759 					sqlNullFloat64: sql.NullFloat64{
    760 						Float64: 2,
    761 					},
    762 					baseJSON:       "[",
    763 					expectedResult: `[2`,
    764 				},
    765 				{
    766 					name: "it should encode a null string",
    767 					sqlNullFloat64: sql.NullFloat64{
    768 						Float64: 2,
    769 					},
    770 					baseJSON:       "[",
    771 					expectedResult: `[2`,
    772 				},
    773 			}
    774 
    775 			for _, testCase := range testCases {
    776 				t.Run(testCase.name, func(t *testing.T) {
    777 					var b strings.Builder
    778 					enc := NewEncoder(&b)
    779 					enc.writeString(testCase.baseJSON)
    780 					enc.AddSQLNullFloat64(&testCase.sqlNullFloat64)
    781 					enc.Write()
    782 					assert.Equal(t, testCase.expectedResult, b.String())
    783 
    784 					var b2 strings.Builder
    785 					enc = NewEncoder(&b2)
    786 					enc.writeString(testCase.baseJSON)
    787 					enc.SQLNullFloat64(&testCase.sqlNullFloat64)
    788 					enc.Write()
    789 					assert.Equal(t, testCase.expectedResult, b2.String())
    790 				})
    791 			}
    792 		},
    793 	)
    794 	t.Run(
    795 		"AddSQLNullFloat64KeyOmitEmpty, is should encode a sql.NullFloat64",
    796 		func(t *testing.T) {
    797 			testCases := []struct {
    798 				name           string
    799 				sqlNullFloat64 sql.NullFloat64
    800 				baseJSON       string
    801 				expectedResult string
    802 				err            bool
    803 			}{
    804 				{
    805 					name: "it should encode a null string",
    806 					sqlNullFloat64: sql.NullFloat64{
    807 						Float64: 2,
    808 						Valid:   true,
    809 					},
    810 					baseJSON:       "[",
    811 					expectedResult: `[2`,
    812 				},
    813 				{
    814 					name: "it should not encode anything as null string is invalid",
    815 					sqlNullFloat64: sql.NullFloat64{
    816 						Float64: 2,
    817 						Valid:   false,
    818 					},
    819 					baseJSON:       "[",
    820 					expectedResult: `[`,
    821 				},
    822 			}
    823 
    824 			for _, testCase := range testCases {
    825 				t.Run(testCase.name, func(t *testing.T) {
    826 					var b strings.Builder
    827 					enc := NewEncoder(&b)
    828 					enc.writeString(testCase.baseJSON)
    829 					enc.AddSQLNullFloat64OmitEmpty(&testCase.sqlNullFloat64)
    830 					enc.Write()
    831 					assert.Equal(t, testCase.expectedResult, b.String())
    832 
    833 					var b2 strings.Builder
    834 					enc = NewEncoder(&b2)
    835 					enc.writeString(testCase.baseJSON)
    836 					enc.SQLNullFloat64OmitEmpty(&testCase.sqlNullFloat64)
    837 					enc.Write()
    838 					assert.Equal(t, testCase.expectedResult, b2.String())
    839 				})
    840 			}
    841 		},
    842 	)
    843 }
    844 
    845 // NullBool
    846 func TestEncoceSQLNullBool(t *testing.T) {
    847 	testCases := []struct {
    848 		name           string
    849 		sqlNullBool    sql.NullBool
    850 		expectedResult string
    851 		err            bool
    852 	}{
    853 		{
    854 			name: "it should encode a null string",
    855 			sqlNullBool: sql.NullBool{
    856 				Bool: true,
    857 			},
    858 			expectedResult: `true`,
    859 		},
    860 		{
    861 			name: "it should return an err as the string is invalid",
    862 			sqlNullBool: sql.NullBool{
    863 				Bool: false,
    864 			},
    865 			expectedResult: `false`,
    866 		},
    867 	}
    868 
    869 	for _, testCase := range testCases {
    870 		t.Run(testCase.name, func(t *testing.T) {
    871 			var b strings.Builder
    872 			enc := NewEncoder(&b)
    873 			err := enc.EncodeSQLNullBool(&testCase.sqlNullBool)
    874 			if testCase.err {
    875 				assert.NotNil(t, err)
    876 			} else {
    877 				assert.Nil(t, err)
    878 				assert.Equal(t, testCase.expectedResult, b.String())
    879 			}
    880 		})
    881 	}
    882 	t.Run(
    883 		"should panic as the encoder is pooled",
    884 		func(t *testing.T) {
    885 			builder := &strings.Builder{}
    886 			enc := NewEncoder(builder)
    887 			enc.isPooled = 1
    888 			defer func() {
    889 				err := recover()
    890 				assert.NotNil(t, err, "err should not be nil")
    891 				assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
    892 			}()
    893 			_ = enc.EncodeSQLNullBool(&sql.NullBool{})
    894 			assert.True(t, false, "should not be called as encoder should have panicked")
    895 		},
    896 	)
    897 
    898 	t.Run(
    899 		"should return an error as the writer encounters an error",
    900 		func(t *testing.T) {
    901 			builder := TestWriterError("")
    902 			enc := NewEncoder(builder)
    903 			err := enc.EncodeSQLNullBool(&sql.NullBool{})
    904 			assert.NotNil(t, err)
    905 		},
    906 	)
    907 }
    908 
    909 func TestAddSQLNullBoolKey(t *testing.T) {
    910 	t.Run(
    911 		"AddSQLNullBoolKey",
    912 		func(t *testing.T) {
    913 			testCases := []struct {
    914 				name           string
    915 				sqlNullBool    sql.NullBool
    916 				baseJSON       string
    917 				expectedResult string
    918 				err            bool
    919 			}{
    920 				{
    921 					name: "it should encode a null string",
    922 					sqlNullBool: sql.NullBool{
    923 						Bool: true,
    924 					},
    925 					baseJSON:       "{",
    926 					expectedResult: `{"foo":true`,
    927 				},
    928 				{
    929 					name: "it should encode a null string",
    930 					sqlNullBool: sql.NullBool{
    931 						Bool: false,
    932 					},
    933 					baseJSON:       "{",
    934 					expectedResult: `{"foo":false`,
    935 				},
    936 				{
    937 					name: "it should encode a null string",
    938 					sqlNullBool: sql.NullBool{
    939 						Bool: true,
    940 					},
    941 					baseJSON:       "{",
    942 					expectedResult: `{"foo":true`,
    943 				},
    944 			}
    945 
    946 			for _, testCase := range testCases {
    947 				t.Run(testCase.name, func(t *testing.T) {
    948 					var b strings.Builder
    949 					enc := NewEncoder(&b)
    950 					enc.writeString(testCase.baseJSON)
    951 					enc.AddSQLNullBoolKey("foo", &testCase.sqlNullBool)
    952 					enc.Write()
    953 					assert.Equal(t, testCase.expectedResult, b.String())
    954 
    955 					var b2 strings.Builder
    956 					enc = NewEncoder(&b2)
    957 					enc.writeString(testCase.baseJSON)
    958 					enc.SQLNullBoolKey("foo", &testCase.sqlNullBool)
    959 					enc.Write()
    960 					assert.Equal(t, testCase.expectedResult, b2.String())
    961 				})
    962 			}
    963 		},
    964 	)
    965 	t.Run(
    966 		"AddSQLNullBoolKeyOmitEmpty, is should encode a sql.NullBool",
    967 		func(t *testing.T) {
    968 			testCases := []struct {
    969 				name           string
    970 				sqlNullBool    sql.NullBool
    971 				baseJSON       string
    972 				expectedResult string
    973 				err            bool
    974 			}{
    975 				{
    976 					name: "it should encode a null string",
    977 					sqlNullBool: sql.NullBool{
    978 						Bool:  true,
    979 						Valid: true,
    980 					},
    981 					baseJSON:       "{",
    982 					expectedResult: `{"foo":true`,
    983 				},
    984 				{
    985 					name: "it should not encode anything as null string is invalid",
    986 					sqlNullBool: sql.NullBool{
    987 						Bool:  true,
    988 						Valid: false,
    989 					},
    990 					baseJSON:       "{",
    991 					expectedResult: `{`,
    992 				},
    993 			}
    994 
    995 			for _, testCase := range testCases {
    996 				t.Run(testCase.name, func(t *testing.T) {
    997 					var b strings.Builder
    998 					enc := NewEncoder(&b)
    999 					enc.writeString(testCase.baseJSON)
   1000 					enc.AddSQLNullBoolKeyOmitEmpty("foo", &testCase.sqlNullBool)
   1001 					enc.Write()
   1002 					assert.Equal(t, testCase.expectedResult, b.String())
   1003 
   1004 					var b2 strings.Builder
   1005 					enc = NewEncoder(&b2)
   1006 					enc.writeString(testCase.baseJSON)
   1007 					enc.SQLNullBoolKeyOmitEmpty("foo", &testCase.sqlNullBool)
   1008 					enc.Write()
   1009 					assert.Equal(t, testCase.expectedResult, b2.String())
   1010 				})
   1011 			}
   1012 		},
   1013 	)
   1014 }
   1015 
   1016 func TestAddSQLNullBool(t *testing.T) {
   1017 	t.Run(
   1018 		"AddSQLNullBool",
   1019 		func(t *testing.T) {
   1020 			testCases := []struct {
   1021 				name           string
   1022 				sqlNullBool    sql.NullBool
   1023 				baseJSON       string
   1024 				expectedResult string
   1025 				err            bool
   1026 			}{
   1027 				{
   1028 					name: "it should encode a null string",
   1029 					sqlNullBool: sql.NullBool{
   1030 						Bool: true,
   1031 					},
   1032 					baseJSON:       "[",
   1033 					expectedResult: `[true`,
   1034 				},
   1035 				{
   1036 					name: "it should encode a null string",
   1037 					sqlNullBool: sql.NullBool{
   1038 						Bool: true,
   1039 					},
   1040 					baseJSON:       "[",
   1041 					expectedResult: `[true`,
   1042 				},
   1043 				{
   1044 					name: "it should encode a null string",
   1045 					sqlNullBool: sql.NullBool{
   1046 						Bool: false,
   1047 					},
   1048 					baseJSON:       "[",
   1049 					expectedResult: `[false`,
   1050 				},
   1051 			}
   1052 
   1053 			for _, testCase := range testCases {
   1054 				t.Run(testCase.name, func(t *testing.T) {
   1055 					var b strings.Builder
   1056 					enc := NewEncoder(&b)
   1057 					enc.writeString(testCase.baseJSON)
   1058 					enc.AddSQLNullBool(&testCase.sqlNullBool)
   1059 					enc.Write()
   1060 					assert.Equal(t, testCase.expectedResult, b.String())
   1061 
   1062 					var b2 strings.Builder
   1063 					enc = NewEncoder(&b2)
   1064 					enc.writeString(testCase.baseJSON)
   1065 					enc.SQLNullBool(&testCase.sqlNullBool)
   1066 					enc.Write()
   1067 					assert.Equal(t, testCase.expectedResult, b2.String())
   1068 				})
   1069 			}
   1070 		},
   1071 	)
   1072 	t.Run(
   1073 		"AddSQLNullBoolKeyOmitEmpty, is should encode a sql.NullBool",
   1074 		func(t *testing.T) {
   1075 			testCases := []struct {
   1076 				name           string
   1077 				sqlNullBool    sql.NullBool
   1078 				baseJSON       string
   1079 				expectedResult string
   1080 				err            bool
   1081 			}{
   1082 				{
   1083 					name: "it should encode a null string",
   1084 					sqlNullBool: sql.NullBool{
   1085 						Bool:  true,
   1086 						Valid: true,
   1087 					},
   1088 					baseJSON:       "[",
   1089 					expectedResult: `[true`,
   1090 				},
   1091 				{
   1092 					name: "it should not encode anything as null string is invalid",
   1093 					sqlNullBool: sql.NullBool{
   1094 						Bool:  true,
   1095 						Valid: false,
   1096 					},
   1097 					baseJSON:       "[",
   1098 					expectedResult: `[`,
   1099 				},
   1100 			}
   1101 
   1102 			for _, testCase := range testCases {
   1103 				t.Run(testCase.name, func(t *testing.T) {
   1104 					var b strings.Builder
   1105 					enc := NewEncoder(&b)
   1106 					enc.writeString(testCase.baseJSON)
   1107 					enc.AddSQLNullBoolOmitEmpty(&testCase.sqlNullBool)
   1108 					enc.Write()
   1109 					assert.Equal(t, testCase.expectedResult, b.String())
   1110 
   1111 					var b2 strings.Builder
   1112 					enc = NewEncoder(&b2)
   1113 					enc.writeString(testCase.baseJSON)
   1114 					enc.SQLNullBoolOmitEmpty(&testCase.sqlNullBool)
   1115 					enc.Write()
   1116 					assert.Equal(t, testCase.expectedResult, b2.String())
   1117 				})
   1118 			}
   1119 		},
   1120 	)
   1121 }
   1122 
   1123 func TestEncoderSQLNullStringEmpty(t *testing.T) {
   1124 	var testCases = []struct {
   1125 		name         string
   1126 		baseJSON     string
   1127 		expectedJSON string
   1128 	}{
   1129 		{
   1130 			name:         "basic 1st elem",
   1131 			baseJSON:     "[",
   1132 			expectedJSON: `[null,"bar"`,
   1133 		},
   1134 		{
   1135 			name:         "basic 2nd elem",
   1136 			baseJSON:     `["test"`,
   1137 			expectedJSON: `["test",null,"bar"`,
   1138 		},
   1139 	}
   1140 	for _, testCase := range testCases {
   1141 		t.Run(testCase.name, func(t *testing.T) {
   1142 			var b strings.Builder
   1143 			var enc = NewEncoder(&b)
   1144 			enc.writeString(testCase.baseJSON)
   1145 			enc.AddSQLNullStringNullEmpty(&sql.NullString{"", true})
   1146 			enc.SQLNullStringNullEmpty(&sql.NullString{"bar", true})
   1147 			enc.Write()
   1148 			assert.Equal(t, testCase.expectedJSON, b.String())
   1149 		})
   1150 	}
   1151 }
   1152 
   1153 func TestEncoderSQLNullStringKeyNullEmpty(t *testing.T) {
   1154 	var testCases = []struct {
   1155 		name         string
   1156 		baseJSON     string
   1157 		expectedJSON string
   1158 	}{
   1159 		{
   1160 			name:         "basic 1st elem",
   1161 			baseJSON:     "{",
   1162 			expectedJSON: `{"foo":null,"bar":"bar"`,
   1163 		},
   1164 		{
   1165 			name:         "basic 2nd elem",
   1166 			baseJSON:     `{"test":"test"`,
   1167 			expectedJSON: `{"test":"test","foo":null,"bar":"bar"`,
   1168 		},
   1169 	}
   1170 	for _, testCase := range testCases {
   1171 		t.Run(testCase.name, func(t *testing.T) {
   1172 			var b strings.Builder
   1173 			var enc = NewEncoder(&b)
   1174 			enc.writeString(testCase.baseJSON)
   1175 			enc.SQLNullStringKeyNullEmpty("foo", &sql.NullString{"", true})
   1176 			enc.SQLNullStringKeyNullEmpty("bar", &sql.NullString{"bar", true})
   1177 			enc.Write()
   1178 			assert.Equal(t, testCase.expectedJSON, b.String())
   1179 		})
   1180 	}
   1181 }
   1182 
   1183 func TestEncoderSQLNullBoolEmpty(t *testing.T) {
   1184 	var testCases = []struct {
   1185 		name         string
   1186 		baseJSON     string
   1187 		expectedJSON string
   1188 	}{
   1189 		{
   1190 			name:         "basic 1st elem",
   1191 			baseJSON:     "[",
   1192 			expectedJSON: `[null,true`,
   1193 		},
   1194 		{
   1195 			name:         "basic 2nd elem",
   1196 			baseJSON:     `["test"`,
   1197 			expectedJSON: `["test",null,true`,
   1198 		},
   1199 	}
   1200 	for _, testCase := range testCases {
   1201 		t.Run(testCase.name, func(t *testing.T) {
   1202 			var b strings.Builder
   1203 			var enc = NewEncoder(&b)
   1204 			enc.writeString(testCase.baseJSON)
   1205 			enc.SQLNullBoolNullEmpty(&sql.NullBool{false, true})
   1206 			enc.SQLNullBoolNullEmpty(&sql.NullBool{true, true})
   1207 			enc.Write()
   1208 			assert.Equal(t, testCase.expectedJSON, b.String())
   1209 		})
   1210 	}
   1211 }
   1212 
   1213 func TestEncoderSQLNullBoolKeyNullEmpty(t *testing.T) {
   1214 	var testCases = []struct {
   1215 		name         string
   1216 		baseJSON     string
   1217 		expectedJSON string
   1218 	}{
   1219 		{
   1220 			name:         "basic 1st elem",
   1221 			baseJSON:     "{",
   1222 			expectedJSON: `{"foo":null,"bar":true`,
   1223 		},
   1224 		{
   1225 			name:         "basic 2nd elem",
   1226 			baseJSON:     `{"test":"test"`,
   1227 			expectedJSON: `{"test":"test","foo":null,"bar":true`,
   1228 		},
   1229 	}
   1230 	for _, testCase := range testCases {
   1231 		t.Run(testCase.name, func(t *testing.T) {
   1232 			var b strings.Builder
   1233 			var enc = NewEncoder(&b)
   1234 			enc.writeString(testCase.baseJSON)
   1235 			enc.AddSQLNullBoolKeyNullEmpty("foo", &sql.NullBool{false, true})
   1236 			enc.SQLNullBoolKeyNullEmpty("bar", &sql.NullBool{true, true})
   1237 			enc.Write()
   1238 			assert.Equal(t, testCase.expectedJSON, b.String())
   1239 		})
   1240 	}
   1241 }
   1242 
   1243 func TestEncoderSQLNullInt64Empty(t *testing.T) {
   1244 	var testCases = []struct {
   1245 		name         string
   1246 		baseJSON     string
   1247 		expectedJSON string
   1248 	}{
   1249 		{
   1250 			name:         "basic 1st elem",
   1251 			baseJSON:     "[",
   1252 			expectedJSON: `[null,1`,
   1253 		},
   1254 		{
   1255 			name:         "basic 2nd elem",
   1256 			baseJSON:     `["test"`,
   1257 			expectedJSON: `["test",null,1`,
   1258 		},
   1259 	}
   1260 	for _, testCase := range testCases {
   1261 		t.Run(testCase.name, func(t *testing.T) {
   1262 			var b strings.Builder
   1263 			var enc = NewEncoder(&b)
   1264 			enc.writeString(testCase.baseJSON)
   1265 			enc.AddSQLNullInt64NullEmpty(&sql.NullInt64{0, true})
   1266 			enc.SQLNullInt64NullEmpty(&sql.NullInt64{1, true})
   1267 			enc.Write()
   1268 			assert.Equal(t, testCase.expectedJSON, b.String())
   1269 		})
   1270 	}
   1271 }
   1272 
   1273 func TestEncoderSQLNullInt64KeyNullEmpty(t *testing.T) {
   1274 	var testCases = []struct {
   1275 		name         string
   1276 		baseJSON     string
   1277 		expectedJSON string
   1278 	}{
   1279 		{
   1280 			name:         "basic 1st elem",
   1281 			baseJSON:     "{",
   1282 			expectedJSON: `{"foo":null,"bar":1`,
   1283 		},
   1284 		{
   1285 			name:         "basic 2nd elem",
   1286 			baseJSON:     `{"test":"test"`,
   1287 			expectedJSON: `{"test":"test","foo":null,"bar":1`,
   1288 		},
   1289 	}
   1290 	for _, testCase := range testCases {
   1291 		t.Run(testCase.name, func(t *testing.T) {
   1292 			var b strings.Builder
   1293 			var enc = NewEncoder(&b)
   1294 			enc.writeString(testCase.baseJSON)
   1295 			enc.AddSQLNullInt64KeyNullEmpty("foo", &sql.NullInt64{0, true})
   1296 			enc.SQLNullInt64KeyNullEmpty("bar", &sql.NullInt64{1, true})
   1297 			enc.Write()
   1298 			assert.Equal(t, testCase.expectedJSON, b.String())
   1299 		})
   1300 	}
   1301 }
   1302 
   1303 func TestEncoderSQLNullFloat64Empty(t *testing.T) {
   1304 	var testCases = []struct {
   1305 		name         string
   1306 		baseJSON     string
   1307 		expectedJSON string
   1308 	}{
   1309 		{
   1310 			name:         "basic 1st elem",
   1311 			baseJSON:     "[",
   1312 			expectedJSON: `[null,1`,
   1313 		},
   1314 		{
   1315 			name:         "basic 2nd elem",
   1316 			baseJSON:     `["test"`,
   1317 			expectedJSON: `["test",null,1`,
   1318 		},
   1319 	}
   1320 	for _, testCase := range testCases {
   1321 		t.Run(testCase.name, func(t *testing.T) {
   1322 			var b strings.Builder
   1323 			var enc = NewEncoder(&b)
   1324 			enc.writeString(testCase.baseJSON)
   1325 			enc.AddSQLNullFloat64NullEmpty(&sql.NullFloat64{0, true})
   1326 			enc.SQLNullFloat64NullEmpty(&sql.NullFloat64{1, true})
   1327 			enc.Write()
   1328 			assert.Equal(t, testCase.expectedJSON, b.String())
   1329 		})
   1330 	}
   1331 }
   1332 
   1333 func TestEncoderSQLNullFloat64KeyNullEmpty(t *testing.T) {
   1334 	var testCases = []struct {
   1335 		name         string
   1336 		baseJSON     string
   1337 		expectedJSON string
   1338 	}{
   1339 		{
   1340 			name:         "basic 1st elem",
   1341 			baseJSON:     "{",
   1342 			expectedJSON: `{"foo":null,"bar":1`,
   1343 		},
   1344 		{
   1345 			name:         "basic 2nd elem",
   1346 			baseJSON:     `{"test":"test"`,
   1347 			expectedJSON: `{"test":"test","foo":null,"bar":1`,
   1348 		},
   1349 	}
   1350 	for _, testCase := range testCases {
   1351 		t.Run(testCase.name, func(t *testing.T) {
   1352 			var b strings.Builder
   1353 			var enc = NewEncoder(&b)
   1354 			enc.writeString(testCase.baseJSON)
   1355 			enc.AddSQLNullFloat64KeyNullEmpty("foo", &sql.NullFloat64{0, true})
   1356 			enc.SQLNullFloat64KeyNullEmpty("bar", &sql.NullFloat64{1, true})
   1357 			enc.Write()
   1358 			assert.Equal(t, testCase.expectedJSON, b.String())
   1359 		})
   1360 	}
   1361 }