commit 75dba3be66f280626f447c63e65179417b651429
parent 75fff352c961091226ab3c6876e46631ecd63e53
Author: francoispqt <francois@parquet.ninja>
Date: Sun, 12 Aug 2018 00:41:03 +0800
sqlnull types
Diffstat:
M | decode_sqlnull_test.go | | | 156 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
A | encode_sqlnull.go | | | 269 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | encode_sqlnull_test.go | | | 1121 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 1542 insertions(+), 4 deletions(-)
diff --git a/decode_sqlnull_test.go b/decode_sqlnull_test.go
@@ -13,21 +13,47 @@ func TestDecodeSQLNullString(t *testing.T) {
name string
json string
expectedNullString sql.NullString
+ err bool
}{
{
name: "basic",
json: `"test"`,
expectedNullString: sql.NullString{String: "test", Valid: true},
},
+ {
+ name: "basic",
+ json: `"test`,
+ expectedNullString: sql.NullString{String: "test", Valid: true},
+ err: true,
+ },
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
nullString := sql.NullString{}
dec := NewDecoder(strings.NewReader(testCase.json))
- dec.DecodeSQLNullString(&nullString)
- assert.Equal(t, testCase.expectedNullString, nullString)
+ err := dec.DecodeSQLNullString(&nullString)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedNullString, nullString)
+ }
})
}
+ t.Run(
+ "should panic because decoder is pooled",
+ func(t *testing.T) {
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnt be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeSQLNullString(&sql.NullString{})
+ assert.True(t, false, "should not be called as decoder should have panicked")
+ },
+ )
}
func TestDecodeSQLNullInt64(t *testing.T) {
@@ -35,19 +61,141 @@ func TestDecodeSQLNullInt64(t *testing.T) {
name string
json string
expectedNullInt64 sql.NullInt64
+ err bool
}{
{
name: "basic",
json: `1`,
expectedNullInt64: sql.NullInt64{Int64: 1, Valid: true},
},
+ {
+ name: "basic",
+ json: `"test`,
+ expectedNullInt64: sql.NullInt64{Int64: 1, Valid: true},
+ err: true,
+ },
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
nullInt64 := sql.NullInt64{}
dec := NewDecoder(strings.NewReader(testCase.json))
- dec.DecodeSQLNullInt64(&nullInt64)
- assert.Equal(t, testCase.expectedNullInt64, nullInt64)
+ err := dec.DecodeSQLNullInt64(&nullInt64)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedNullInt64, nullInt64)
+ }
+ })
+ }
+ t.Run(
+ "should panic because decoder is pooled",
+ func(t *testing.T) {
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnt be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeSQLNullInt64(&sql.NullInt64{})
+ assert.True(t, false, "should not be called as decoder should have panicked")
+ },
+ )
+}
+
+func TestDecodeSQLNullFloat64(t *testing.T) {
+ testCases := []struct {
+ name string
+ json string
+ expectedNullFloat64 sql.NullFloat64
+ err bool
+ }{
+ {
+ name: "basic",
+ json: `1`,
+ expectedNullFloat64: sql.NullFloat64{Float64: 1, Valid: true},
+ },
+ {
+ name: "basic",
+ json: `"test`,
+ expectedNullFloat64: sql.NullFloat64{Float64: 1, Valid: true},
+ err: true,
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ nullFloat64 := sql.NullFloat64{}
+ dec := NewDecoder(strings.NewReader(testCase.json))
+ err := dec.DecodeSQLNullFloat64(&nullFloat64)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedNullFloat64, nullFloat64)
+ }
+ })
+ }
+ t.Run(
+ "should panic because decoder is pooled",
+ func(t *testing.T) {
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnt be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeSQLNullFloat64(&sql.NullFloat64{})
+ assert.True(t, false, "should not be called as decoder should have panicked")
+ },
+ )
+}
+
+func TestDecodeSQLNullBool(t *testing.T) {
+ testCases := []struct {
+ name string
+ json string
+ expectedNullBool sql.NullBool
+ err bool
+ }{
+ {
+ name: "basic",
+ json: `true`,
+ expectedNullBool: sql.NullBool{Bool: true, Valid: true},
+ },
+ {
+ name: "basic",
+ json: `"&`,
+ expectedNullBool: sql.NullBool{Bool: true, Valid: true},
+ err: true,
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ nullBool := sql.NullBool{}
+ dec := NewDecoder(strings.NewReader(testCase.json))
+ err := dec.DecodeSQLNullBool(&nullBool)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedNullBool, nullBool)
+ }
})
}
+ t.Run(
+ "should panic because decoder is pooled",
+ func(t *testing.T) {
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnt be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeSQLNullBool(&sql.NullBool{})
+ assert.True(t, false, "should not be called as decoder should have panicked")
+ },
+ )
}
diff --git a/encode_sqlnull.go b/encode_sqlnull.go
@@ -0,0 +1,269 @@
+package gojay
+
+import "database/sql"
+
+// EncodeSQLNullString encodes a string to
+func (enc *Encoder) EncodeSQLNullString(v *sql.NullString) error {
+ if enc.isPooled == 1 {
+ panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
+ }
+ _, _ = enc.encodeString(v.String)
+ _, err := enc.Write()
+ if err != nil {
+ enc.err = err
+ return err
+ }
+ return nil
+}
+
+// AddSQLNullString adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullString(v *sql.NullString) {
+ enc.String(v.String)
+}
+
+// AddSQLNullStringOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullStringOmitEmpty(v *sql.NullString) {
+ if v != nil && v.Valid && v.String != "" {
+ enc.StringOmitEmpty(v.String)
+ }
+}
+
+// AddSQLNullStringKey adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullStringKey(key string, v *sql.NullString) {
+ enc.StringKey(key, v.String)
+}
+
+// AddSQLNullStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullStringKeyOmitEmpty(key string, v *sql.NullString) {
+ if v != nil && v.Valid && v.String != "" {
+ enc.StringKeyOmitEmpty(key, v.String)
+ }
+}
+
+// SQLNullString adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullString(v *sql.NullString) {
+ enc.String(v.String)
+}
+
+// SQLNullStringOmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullStringOmitEmpty(v *sql.NullString) {
+ if v != nil && v.Valid && v.String != "" {
+ enc.String(v.String)
+ }
+}
+
+// SQLNullStringKey adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullStringKey(key string, v *sql.NullString) {
+ enc.StringKey(key, v.String)
+}
+
+// SQLNullStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullStringKeyOmitEmpty(key string, v *sql.NullString) {
+ if v != nil && v.Valid && v.String != "" {
+ enc.StringKeyOmitEmpty(key, v.String)
+ }
+}
+
+// NullInt64
+
+// EncodeSQLNullInt64 encodes a string to
+func (enc *Encoder) EncodeSQLNullInt64(v *sql.NullInt64) error {
+ if enc.isPooled == 1 {
+ panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
+ }
+ _, _ = enc.encodeInt64(v.Int64)
+ _, err := enc.Write()
+ if err != nil {
+ enc.err = err
+ return err
+ }
+ return nil
+}
+
+// AddSQLNullInt64 adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullInt64(v *sql.NullInt64) {
+ enc.Int64(v.Int64)
+}
+
+// AddSQLNullInt64OmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullInt64OmitEmpty(v *sql.NullInt64) {
+ if v != nil && v.Valid && v.Int64 != 0 {
+ enc.Int64OmitEmpty(v.Int64)
+ }
+}
+
+// AddSQLNullInt64Key adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullInt64Key(key string, v *sql.NullInt64) {
+ enc.Int64Key(key, v.Int64)
+}
+
+// AddSQLNullInt64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullInt64KeyOmitEmpty(key string, v *sql.NullInt64) {
+ if v != nil && v.Valid && v.Int64 != 0 {
+ enc.Int64KeyOmitEmpty(key, v.Int64)
+ }
+}
+
+// SQLNullInt64 adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullInt64(v *sql.NullInt64) {
+ enc.Int64(v.Int64)
+}
+
+// SQLNullInt64OmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullInt64OmitEmpty(v *sql.NullInt64) {
+ if v != nil && v.Valid && v.Int64 != 0 {
+ enc.Int64(v.Int64)
+ }
+}
+
+// SQLNullInt64Key adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullInt64Key(key string, v *sql.NullInt64) {
+ enc.Int64Key(key, v.Int64)
+}
+
+// SQLNullInt64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullInt64KeyOmitEmpty(key string, v *sql.NullInt64) {
+ if v != nil && v.Valid && v.Int64 != 0 {
+ enc.Int64KeyOmitEmpty(key, v.Int64)
+ }
+}
+
+// NullFloat64
+
+// EncodeSQLNullFloat64 encodes a string to
+func (enc *Encoder) EncodeSQLNullFloat64(v *sql.NullFloat64) error {
+ if enc.isPooled == 1 {
+ panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
+ }
+ _, _ = enc.encodeFloat(v.Float64)
+ _, err := enc.Write()
+ if err != nil {
+ enc.err = err
+ return err
+ }
+ return nil
+}
+
+// AddSQLNullFloat64 adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullFloat64(v *sql.NullFloat64) {
+ enc.Float64(v.Float64)
+}
+
+// AddSQLNullFloat64OmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullFloat64OmitEmpty(v *sql.NullFloat64) {
+ if v != nil && v.Valid && v.Float64 != 0 {
+ enc.Float64OmitEmpty(v.Float64)
+ }
+}
+
+// AddSQLNullFloat64Key adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullFloat64Key(key string, v *sql.NullFloat64) {
+ enc.Float64Key(key, v.Float64)
+}
+
+// AddSQLNullFloat64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullFloat64KeyOmitEmpty(key string, v *sql.NullFloat64) {
+ if v != nil && v.Valid && v.Float64 != 0 {
+ enc.Float64KeyOmitEmpty(key, v.Float64)
+ }
+}
+
+// SQLNullFloat64 adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullFloat64(v *sql.NullFloat64) {
+ enc.Float64(v.Float64)
+}
+
+// SQLNullFloat64OmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullFloat64OmitEmpty(v *sql.NullFloat64) {
+ if v != nil && v.Valid && v.Float64 != 0 {
+ enc.Float64(v.Float64)
+ }
+}
+
+// SQLNullFloat64Key adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullFloat64Key(key string, v *sql.NullFloat64) {
+ enc.Float64Key(key, v.Float64)
+}
+
+// SQLNullFloat64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullFloat64KeyOmitEmpty(key string, v *sql.NullFloat64) {
+ if v != nil && v.Valid && v.Float64 != 0 {
+ enc.Float64KeyOmitEmpty(key, v.Float64)
+ }
+}
+
+// NullBool
+
+// EncodeSQLNullBool encodes a string to
+func (enc *Encoder) EncodeSQLNullBool(v *sql.NullBool) error {
+ if enc.isPooled == 1 {
+ panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
+ }
+ _, _ = enc.encodeBool(v.Bool)
+ _, err := enc.Write()
+ if err != nil {
+ enc.err = err
+ return err
+ }
+ return nil
+}
+
+// AddSQLNullBool adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullBool(v *sql.NullBool) {
+ enc.Bool(v.Bool)
+}
+
+// AddSQLNullBoolOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside a slice or array encoding (does not encode a key)
+func (enc *Encoder) AddSQLNullBoolOmitEmpty(v *sql.NullBool) {
+ if v != nil && v.Valid && v.Bool != false {
+ enc.BoolOmitEmpty(v.Bool)
+ }
+}
+
+// AddSQLNullBoolKey adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullBoolKey(key string, v *sql.NullBool) {
+ enc.BoolKey(key, v.Bool)
+}
+
+// AddSQLNullBoolKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) AddSQLNullBoolKeyOmitEmpty(key string, v *sql.NullBool) {
+ if v != nil && v.Valid && v.Bool != false {
+ enc.BoolKeyOmitEmpty(key, v.Bool)
+ }
+}
+
+// SQLNullBool adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullBool(v *sql.NullBool) {
+ enc.Bool(v.Bool)
+}
+
+// SQLNullBoolOmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullBoolOmitEmpty(v *sql.NullBool) {
+ if v != nil && v.Valid && v.Bool != false {
+ enc.Bool(v.Bool)
+ }
+}
+
+// SQLNullBoolKey adds a string to be encoded, must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullBoolKey(key string, v *sql.NullBool) {
+ enc.BoolKey(key, v.Bool)
+}
+
+// SQLNullBoolKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
+// Must be used inside an object as it will encode a key
+func (enc *Encoder) SQLNullBoolKeyOmitEmpty(key string, v *sql.NullBool) {
+ if v != nil && v.Valid && v.Bool != false {
+ enc.BoolKeyOmitEmpty(key, v.Bool)
+ }
+}
diff --git a/encode_sqlnull_test.go b/encode_sqlnull_test.go
@@ -0,0 +1,1121 @@
+package gojay
+
+import (
+ "database/sql"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+// Null String
+func TestEncoceSQLNullString(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullString sql.NullString
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo bar",
+ },
+ expectedResult: `"foo bar"`,
+ },
+ {
+ name: "it should return an err as the string is invalid",
+ sqlNullString: sql.NullString{
+ String: "foo \t bar",
+ },
+ expectedResult: `"foo \t bar"`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ err := enc.EncodeSQLNullString(&testCase.sqlNullString)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedResult, b.String())
+ }
+ })
+ }
+
+ t.Run(
+ "should panic as the encoder is pooled",
+ func(t *testing.T) {
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ enc.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err should not be nil")
+ assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
+ }()
+ _ = enc.EncodeSQLNullString(&sql.NullString{})
+ assert.True(t, false, "should not be called as encoder should have panicked")
+ },
+ )
+
+ t.Run(
+ "should return an error as the writer encounters an error",
+ func(t *testing.T) {
+ builder := TestWriterError("")
+ enc := NewEncoder(builder)
+ err := enc.EncodeSQLNullString(&sql.NullString{})
+ assert.NotNil(t, err)
+ },
+ )
+}
+
+func TestAddSQLNullStringKey(t *testing.T) {
+ t.Run(
+ "AddSQLNullStringKey",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullString sql.NullString
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo bar",
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":"foo bar"`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo \t bar",
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":"foo \t bar"`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo \t bar",
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":"foo \t bar"`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullStringKey("foo", &testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullStringKey("foo", &testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullStringKeyOmitEmpty, is should encode a sql.NullString",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullString sql.NullString
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo bar",
+ Valid: true,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":"foo bar"`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullString: sql.NullString{
+ String: "foo \t bar",
+ Valid: false,
+ },
+ baseJSON: "{",
+ expectedResult: `{`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullStringKeyOmitEmpty("foo", &testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullStringKeyOmitEmpty("foo", &testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}
+
+func TestAddSQLNullString(t *testing.T) {
+ t.Run(
+ "AddSQLNullString",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullString sql.NullString
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo bar",
+ },
+ baseJSON: "[",
+ expectedResult: `["foo bar"`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo \t bar",
+ },
+ baseJSON: "[",
+ expectedResult: `["foo \t bar"`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo \t bar",
+ },
+ baseJSON: "[",
+ expectedResult: `["foo \t bar"`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullString(&testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullString(&testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullStringKeyOmitEmpty, is should encode a sql.NullString",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullString sql.NullString
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullString: sql.NullString{
+ String: "foo bar",
+ Valid: true,
+ },
+ baseJSON: "[",
+ expectedResult: `["foo bar"`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullString: sql.NullString{
+ String: "foo \t bar",
+ Valid: false,
+ },
+ baseJSON: "[",
+ expectedResult: `[`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullStringOmitEmpty(&testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullStringOmitEmpty(&testCase.sqlNullString)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}
+
+// NullInt64
+func TestEncoceSQLNullInt64(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullInt64 sql.NullInt64
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: int64(1),
+ },
+ expectedResult: `1`,
+ },
+ {
+ name: "it should return an err as the string is invalid",
+ sqlNullInt64: sql.NullInt64{
+ Int64: int64(2),
+ },
+ expectedResult: `2`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ err := enc.EncodeSQLNullInt64(&testCase.sqlNullInt64)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedResult, b.String())
+ }
+ })
+ }
+ t.Run(
+ "should panic as the encoder is pooled",
+ func(t *testing.T) {
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ enc.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err should not be nil")
+ assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
+ }()
+ _ = enc.EncodeSQLNullInt64(&sql.NullInt64{})
+ assert.True(t, false, "should not be called as encoder should have panicked")
+ },
+ )
+ t.Run(
+ "should return an error as the writer encounters an error",
+ func(t *testing.T) {
+ builder := TestWriterError("")
+ enc := NewEncoder(builder)
+ err := enc.EncodeSQLNullInt64(&sql.NullInt64{})
+ assert.NotNil(t, err)
+ },
+ )
+}
+
+func TestAddSQLNullInt64Key(t *testing.T) {
+ t.Run(
+ "AddSQLNullInt64Key",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullInt64 sql.NullInt64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 1,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":1`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 2,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":2`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 2,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":2`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullInt64Key("foo", &testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullInt64Key("foo", &testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullInt64KeyOmitEmpty, is should encode a sql.NullInt64",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullInt64 sql.NullInt64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 1,
+ Valid: true,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":1`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 2,
+ Valid: false,
+ },
+ baseJSON: "{",
+ expectedResult: `{`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullInt64KeyOmitEmpty("foo", &testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullInt64KeyOmitEmpty("foo", &testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}
+
+func TestAddSQLNullInt64(t *testing.T) {
+ t.Run(
+ "AddSQLNullInt64",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullInt64 sql.NullInt64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 1,
+ },
+ baseJSON: "[",
+ expectedResult: `[1`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 2,
+ },
+ baseJSON: "[",
+ expectedResult: `[2`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 2,
+ },
+ baseJSON: "[",
+ expectedResult: `[2`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullInt64(&testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullInt64(&testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullInt64KeyOmitEmpty, is should encode a sql.NullInt64",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullInt64 sql.NullInt64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 2,
+ Valid: true,
+ },
+ baseJSON: "[",
+ expectedResult: `[2`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullInt64: sql.NullInt64{
+ Int64: 2,
+ Valid: false,
+ },
+ baseJSON: "[",
+ expectedResult: `[`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullInt64OmitEmpty(&testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullInt64OmitEmpty(&testCase.sqlNullInt64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}
+
+// NullFloat64
+func TestEncoceSQLNullFloat64(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullFloat64 sql.NullFloat64
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: float64(1),
+ },
+ expectedResult: `1`,
+ },
+ {
+ name: "it should return an err as the string is invalid",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: float64(2),
+ },
+ expectedResult: `2`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ err := enc.EncodeSQLNullFloat64(&testCase.sqlNullFloat64)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedResult, b.String())
+ }
+ })
+ }
+ t.Run(
+ "should panic as the encoder is pooled",
+ func(t *testing.T) {
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ enc.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err should not be nil")
+ assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
+ }()
+ _ = enc.EncodeSQLNullFloat64(&sql.NullFloat64{})
+ assert.True(t, false, "should not be called as encoder should have panicked")
+ },
+ )
+
+ t.Run(
+ "should return an error as the writer encounters an error",
+ func(t *testing.T) {
+ builder := TestWriterError("")
+ enc := NewEncoder(builder)
+ err := enc.EncodeSQLNullFloat64(&sql.NullFloat64{})
+ assert.NotNil(t, err)
+ },
+ )
+}
+
+func TestAddSQLNullFloat64Key(t *testing.T) {
+ t.Run(
+ "AddSQLNullFloat64Key",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullFloat64 sql.NullFloat64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 1,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":1`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 2,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":2`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 2,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":2`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullFloat64Key("foo", &testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullFloat64Key("foo", &testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullFloat64KeyOmitEmpty, is should encode a sql.NullFloat64",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullFloat64 sql.NullFloat64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 1,
+ Valid: true,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":1`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 2,
+ Valid: false,
+ },
+ baseJSON: "{",
+ expectedResult: `{`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullFloat64KeyOmitEmpty("foo", &testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullFloat64KeyOmitEmpty("foo", &testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}
+
+func TestAddSQLNullFloat64(t *testing.T) {
+ t.Run(
+ "AddSQLNullFloat64",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullFloat64 sql.NullFloat64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 1,
+ },
+ baseJSON: "[",
+ expectedResult: `[1`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 2,
+ },
+ baseJSON: "[",
+ expectedResult: `[2`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 2,
+ },
+ baseJSON: "[",
+ expectedResult: `[2`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullFloat64(&testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullFloat64(&testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullFloat64KeyOmitEmpty, is should encode a sql.NullFloat64",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullFloat64 sql.NullFloat64
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 2,
+ Valid: true,
+ },
+ baseJSON: "[",
+ expectedResult: `[2`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullFloat64: sql.NullFloat64{
+ Float64: 2,
+ Valid: false,
+ },
+ baseJSON: "[",
+ expectedResult: `[`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullFloat64OmitEmpty(&testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullFloat64OmitEmpty(&testCase.sqlNullFloat64)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}
+
+// NullBool
+func TestEncoceSQLNullBool(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullBool sql.NullBool
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ },
+ expectedResult: `true`,
+ },
+ {
+ name: "it should return an err as the string is invalid",
+ sqlNullBool: sql.NullBool{
+ Bool: false,
+ },
+ expectedResult: `false`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ err := enc.EncodeSQLNullBool(&testCase.sqlNullBool)
+ if testCase.err {
+ assert.NotNil(t, err)
+ } else {
+ assert.Nil(t, err)
+ assert.Equal(t, testCase.expectedResult, b.String())
+ }
+ })
+ }
+ t.Run(
+ "should panic as the encoder is pooled",
+ func(t *testing.T) {
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ enc.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err should not be nil")
+ assert.IsType(t, InvalidUsagePooledEncoderError(""), err, "err should be of type InvalidUsagePooledEncoderError")
+ }()
+ _ = enc.EncodeSQLNullBool(&sql.NullBool{})
+ assert.True(t, false, "should not be called as encoder should have panicked")
+ },
+ )
+
+ t.Run(
+ "should return an error as the writer encounters an error",
+ func(t *testing.T) {
+ builder := TestWriterError("")
+ enc := NewEncoder(builder)
+ err := enc.EncodeSQLNullBool(&sql.NullBool{})
+ assert.NotNil(t, err)
+ },
+ )
+}
+
+func TestAddSQLNullBoolKey(t *testing.T) {
+ t.Run(
+ "AddSQLNullBoolKey",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullBool sql.NullBool
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":true`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: false,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":false`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":true`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullBoolKey("foo", &testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullBoolKey("foo", &testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullBoolKeyOmitEmpty, is should encode a sql.NullBool",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullBool sql.NullBool
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ Valid: true,
+ },
+ baseJSON: "{",
+ expectedResult: `{"foo":true`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ Valid: false,
+ },
+ baseJSON: "{",
+ expectedResult: `{`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullBoolKeyOmitEmpty("foo", &testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullBoolKeyOmitEmpty("foo", &testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}
+
+func TestAddSQLNullBool(t *testing.T) {
+ t.Run(
+ "AddSQLNullBool",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullBool sql.NullBool
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ },
+ baseJSON: "[",
+ expectedResult: `[true`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ },
+ baseJSON: "[",
+ expectedResult: `[true`,
+ },
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: false,
+ },
+ baseJSON: "[",
+ expectedResult: `[false`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullBool(&testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullBool(&testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+ t.Run(
+ "AddSQLNullBoolKeyOmitEmpty, is should encode a sql.NullBool",
+ func(t *testing.T) {
+ testCases := []struct {
+ name string
+ sqlNullBool sql.NullBool
+ baseJSON string
+ expectedResult string
+ err bool
+ }{
+ {
+ name: "it should encode a null string",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ Valid: true,
+ },
+ baseJSON: "[",
+ expectedResult: `[true`,
+ },
+ {
+ name: "it should not encode anything as null string is invalid",
+ sqlNullBool: sql.NullBool{
+ Bool: true,
+ Valid: false,
+ },
+ baseJSON: "[",
+ expectedResult: `[`,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ var b strings.Builder
+ enc := NewEncoder(&b)
+ enc.writeString(testCase.baseJSON)
+ enc.AddSQLNullBoolOmitEmpty(&testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b.String())
+
+ var b2 strings.Builder
+ enc = NewEncoder(&b2)
+ enc.writeString(testCase.baseJSON)
+ enc.SQLNullBoolOmitEmpty(&testCase.sqlNullBool)
+ enc.Write()
+ assert.Equal(t, testCase.expectedResult, b2.String())
+ })
+ }
+ },
+ )
+}