Skip to content

Commit

Permalink
Merge pull request #612 from Icinga/bool-binary-unixmilli-marshaljson…
Browse files Browse the repository at this point in the history
…-return-valid-json-not-empty-string

{Bool,Binary,UnixMilli}#MarshalJSON(): return valid JSON, not empty string
  • Loading branch information
julianbrost authored Jul 25, 2023
2 parents 3d66bec + b8ed25c commit ef09059
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pkg/types/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
29 changes: 29 additions & 0 deletions pkg/types/binary_test.go
Original file line number Diff line number Diff line change
@@ -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))
})
}
}
2 changes: 1 addition & 1 deletion pkg/types/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
30 changes: 30 additions & 0 deletions pkg/types/bool_test.go
Original file line number Diff line number Diff line change
@@ -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))
})
}
}
2 changes: 1 addition & 1 deletion pkg/types/unix_milli.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 30 additions & 0 deletions pkg/types/unix_milli_test.go
Original file line number Diff line number Diff line change
@@ -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))
})
}
}

0 comments on commit ef09059

Please sign in to comment.