diff --git a/pkg/types/binary.go b/pkg/types/binary.go index 00a5417f..9fb0a9f4 100644 --- a/pkg/types/binary.go +++ b/pkg/types/binary.go @@ -65,7 +65,7 @@ func (binary *Binary) UnmarshalText(text []byte) error { // Supports JSON null. func (binary Binary) MarshalJSON() ([]byte, error) { if !binary.Valid() { - return nil, nil + return []byte("null"), nil } return internal.MarshalJSON(binary.String()) diff --git a/pkg/types/binary_test.go b/pkg/types/binary_test.go new file mode 100644 index 00000000..2a4f8292 --- /dev/null +++ b/pkg/types/binary_test.go @@ -0,0 +1,29 @@ +package types + +import ( + "github.com/stretchr/testify/require" + "testing" + "unicode/utf8" +) + +func TestBinary_MarshalJSON(t *testing.T) { + subtests := []struct { + name string + input Binary + output string + }{ + {"nil", nil, `null`}, + {"empty", make(Binary, 0, 1), `null`}, + {"space", Binary(" "), `"20"`}, + } + + for _, st := range subtests { + t.Run(st.name, func(t *testing.T) { + actual, err := st.input.MarshalJSON() + + require.NoError(t, err) + require.True(t, utf8.Valid(actual)) + require.Equal(t, st.output, string(actual)) + }) + } +} diff --git a/pkg/types/bool.go b/pkg/types/bool.go index 43302640..2b96c099 100644 --- a/pkg/types/bool.go +++ b/pkg/types/bool.go @@ -26,7 +26,7 @@ type Bool struct { // MarshalJSON implements the json.Marshaler interface. func (b Bool) MarshalJSON() ([]byte, error) { if !b.Valid { - return nil, nil + return []byte("null"), nil } return internal.MarshalJSON(b.Bool) diff --git a/pkg/types/bool_test.go b/pkg/types/bool_test.go new file mode 100644 index 00000000..fe49588c --- /dev/null +++ b/pkg/types/bool_test.go @@ -0,0 +1,30 @@ +package types + +import ( + "fmt" + "github.com/stretchr/testify/require" + "testing" + "unicode/utf8" +) + +func TestBool_MarshalJSON(t *testing.T) { + subtests := []struct { + input Bool + output string + }{ + {Bool{Bool: false, Valid: false}, `null`}, + {Bool{Bool: false, Valid: true}, `false`}, + {Bool{Bool: true, Valid: false}, `null`}, + {Bool{Bool: true, Valid: true}, `true`}, + } + + for _, st := range subtests { + t.Run(fmt.Sprintf("Bool-%#v_Valid-%#v", st.input.Bool, st.input.Valid), func(t *testing.T) { + actual, err := st.input.MarshalJSON() + + require.NoError(t, err) + require.True(t, utf8.Valid(actual)) + require.Equal(t, st.output, string(actual)) + }) + } +} diff --git a/pkg/types/unix_milli.go b/pkg/types/unix_milli.go index 203cdf6e..3f6f988f 100644 --- a/pkg/types/unix_milli.go +++ b/pkg/types/unix_milli.go @@ -24,7 +24,7 @@ func (t UnixMilli) Time() time.Time { // Marshals to milliseconds. Supports JSON null. func (t UnixMilli) MarshalJSON() ([]byte, error) { if time.Time(t).IsZero() { - return nil, nil + return []byte("null"), nil } return []byte(strconv.FormatInt(time.Time(t).UnixMilli(), 10)), nil diff --git a/pkg/types/unix_milli_test.go b/pkg/types/unix_milli_test.go new file mode 100644 index 00000000..985fa2ac --- /dev/null +++ b/pkg/types/unix_milli_test.go @@ -0,0 +1,30 @@ +package types + +import ( + "github.com/stretchr/testify/require" + "testing" + "time" + "unicode/utf8" +) + +func TestUnixMilli_MarshalJSON(t *testing.T) { + subtests := []struct { + name string + input UnixMilli + output string + }{ + {"zero", UnixMilli{}, `null`}, + {"epoch", UnixMilli(time.Unix(0, 0)), `0`}, + {"nonzero", UnixMilli(time.Unix(1234567890, 62500000)), `1234567890062`}, + } + + for _, st := range subtests { + t.Run(st.name, func(t *testing.T) { + actual, err := st.input.MarshalJSON() + + require.NoError(t, err) + require.True(t, utf8.Valid(actual)) + require.Equal(t, st.output, string(actual)) + }) + } +}