package utils import ( "encoding/json" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( _ json.Unmarshaler = &Optional[int]{} _ json.Unmarshaler = &Optional[string]{} ) type WithOptionals struct { IntField1 Optional[int] IntField2 Optional[int] `json:"int_field_2"` } func TestOptional(t *testing.T) { t.Run("Default should be implicit nulls", func(t *testing.T) { var data WithOptionals assert.False(t, data.IntField1.Explicit()) assert.Nil(t, data.IntField1.Value()) assert.False(t, data.IntField2.Explicit()) assert.Nil(t, data.IntField2.Value()) }) } func TestOptional_Unmarshal(t *testing.T) { t.Run("Implicit null", func(t *testing.T) { var data WithOptionals const text = `{}` err := json.Unmarshal([]byte(text), &data) require.NoError(t, err) assert.False(t, data.IntField1.Explicit()) assert.Nil(t, data.IntField1.Value()) assert.False(t, data.IntField2.Explicit()) assert.Nil(t, data.IntField2.Value()) }) t.Run("Explicit nulls", func(t *testing.T) { var data WithOptionals const text = `{ "IntField1": null, "int_field_2": null }` err := json.Unmarshal([]byte(text), &data) require.NoError(t, err) assert.True(t, data.IntField1.Explicit()) assert.Nil(t, data.IntField1.Value()) assert.True(t, data.IntField2.Explicit()) assert.Nil(t, data.IntField2.Value()) }) t.Run(`Explicit string "null" should fail`, func(t *testing.T) { var data WithOptionals const text = `{ "IntField1": "null", "int_field_2": "null" }` err := json.Unmarshal([]byte(text), &data) require.Error(t, err) }) t.Run("Happy scenario", func(t *testing.T) { var data WithOptionals const text = `{ "IntField1": 123, "int_field_2": 456 }` err := json.Unmarshal([]byte(text), &data) require.NoError(t, err) assert.True(t, data.IntField1.Explicit()) assert.Equal(t, 123, *data.IntField1.Value()) assert.True(t, data.IntField2.Explicit()) assert.Equal(t, 456, *data.IntField2.Value()) }) }