Skip to content

Commit

Permalink
add unit test for complex struct
Browse files Browse the repository at this point in the history
Signed-off-by: Ashutosh Kumar <[email protected]>
  • Loading branch information
sonasingh46 committed Jan 9, 2024
1 parent 09846bc commit e6e916a
Showing 1 changed file with 185 additions and 40 deletions.
225 changes: 185 additions & 40 deletions types/nullable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package types
import (
"encoding/json"
"fmt"
"testing"

"github.com/oapi-codegen/nullable"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
)

type SimpleStringNullableRequired struct {
Expand Down Expand Up @@ -279,55 +280,54 @@ func TestNullableOptional_UnmarshalJSON(t *testing.T) {
type testCase struct {
name string
json []byte
assert func(obj SimpleIntNullableOptional, t *testing.T)
assert func(t *testing.T, obj SimpleIntNullableOptional)
}
tests := []testCase{
{
name: "when not provided",
json: []byte(`{}`),
assert: func(obj SimpleIntNullableOptional, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableOptional) {
t.Helper()

assert.Equalf(t, false, obj.ReplicaCount.IsSpecified(), "replica count should not be set")
assert.Equalf(t, false, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Falsef(t, obj.ReplicaCount.IsSpecified(), "replica count should not be set")
assert.Falsef(t, obj.ReplicaCount.IsNull(), "replica count should not be null")
},
},

{
name: "when explicitly set to zero value",
json: []byte(`{"replica_count":0}`),
assert: func(obj SimpleIntNullableOptional, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableOptional) {
t.Helper()

assert.Equalf(t, true, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Equalf(t, false, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Truef(t, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Falsef(t, obj.ReplicaCount.IsNull(), "replica count should not be null")

val, err := obj.ReplicaCount.Get()
require.NoError(t, err)
assert.Equalf(t, 0, val, "replica count value should be 0")

},
},

{
name: "when explicitly set to null value",
json: []byte(`{"replica_count":null}`),
assert: func(obj SimpleIntNullableOptional, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableOptional) {
t.Helper()

assert.Equalf(t, true, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Equalf(t, true, obj.ReplicaCount.IsNull(), "replica count should be null")
assert.Truef(t, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Truef(t, obj.ReplicaCount.IsNull(), "replica count should be null")
},
},

{
name: "when explicitly set to a specific value",
json: []byte(`{"replica_count":5}`),
assert: func(obj SimpleIntNullableOptional, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableOptional) {
t.Helper()

assert.Equalf(t, true, obj.ReplicaCount.IsSpecified(), "replica count should not be null")
assert.Equalf(t, false, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Truef(t, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Falsef(t, obj.ReplicaCount.IsNull(), "replica count should not be null")

val, err := obj.ReplicaCount.Get()
require.NoError(t, err)
Expand All @@ -340,7 +340,8 @@ func TestNullableOptional_UnmarshalJSON(t *testing.T) {
var obj SimpleIntNullableOptional
err := json.Unmarshal(tt.json, &obj)
require.NoError(t, err)
tt.assert(obj, t)

tt.assert(t, obj)
})
}
}
Expand Down Expand Up @@ -403,7 +404,7 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
type testCase struct {
name string
json []byte
assert func(obj SimpleIntNullableRequired, t *testing.T)
assert func(t *testing.T, obj SimpleIntNullableRequired)
}
tests := []testCase{
{
Expand All @@ -412,22 +413,22 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
// the behaviour
name: "when not provided",
json: []byte(`{}`),
assert: func(obj SimpleIntNullableRequired, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableRequired) {
t.Helper()

assert.Equalf(t, false, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Equalf(t, false, obj.ReplicaCount.IsSpecified(), "replica count should not be set")
assert.Falsef(t, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Falsef(t, obj.ReplicaCount.IsSpecified(), "replica count should not be set")
},
},

{
name: "when explicitly set to zero value",
json: []byte(`{"replica_count":0}`),
assert: func(obj SimpleIntNullableRequired, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableRequired) {
t.Helper()

assert.Equalf(t, false, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Equalf(t, true, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Falsef(t, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Truef(t, obj.ReplicaCount.IsSpecified(), "replica count should be set")

val, err := obj.ReplicaCount.Get()
require.NoError(t, err)
Expand All @@ -438,22 +439,22 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
{
name: "when explicitly set to null value",
json: []byte(`{"replica_count":null}`),
assert: func(obj SimpleIntNullableRequired, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableRequired) {
t.Helper()

assert.Equalf(t, true, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Equalf(t, true, obj.ReplicaCount.IsNull(), "replica count should be null")
assert.Truef(t, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Truef(t, obj.ReplicaCount.IsNull(), "replica count should be null")
},
},

{
name: "when explicitly set to a specific value",
json: []byte(`{"replica_count":5}`),
assert: func(obj SimpleIntNullableRequired, t *testing.T) {
assert: func(t *testing.T, obj SimpleIntNullableRequired) {
t.Helper()

assert.Equalf(t, false, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Equalf(t, true, obj.ReplicaCount.IsSpecified(), "replica count should be set")
assert.Falsef(t, obj.ReplicaCount.IsNull(), "replica count should not be null")
assert.Truef(t, obj.ReplicaCount.IsSpecified(), "replica count should be set")

val, err := obj.ReplicaCount.Get()
require.NoError(t, err)
Expand All @@ -466,35 +467,179 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
var obj SimpleIntNullableRequired
err := json.Unmarshal(tt.json, &obj)
require.NoError(t, err)
tt.assert(obj, t)

tt.assert(t, obj)
})
}
}

type ComplexNullable struct {
Config nullable.Nullable[Config] `json:"config,omitempty"`
Location nullable.Nullable[string] `json:"location"`
NodeCount nullable.Nullable[int] `json:"node_count,omitempty"`
}

type Config struct {
CPU nullable.Nullable[string] `json:"cpu,omitempty"`
RAM nullable.Nullable[string] `json:"ram,omitempty"`
}

func TestComplexNullable(t *testing.T) {
type testCase struct {
name string
jsonInput []byte
assert func(t *testing.T, obj ComplexNullable)
}
tests := []testCase{
{
name: "complex object: empty value",
jsonInput: []byte(`{}`),
assert: func(t *testing.T, obj ComplexNullable) {
t.Helper()

assert.Falsef(t, obj.Config.IsSpecified(), "config should not be set")
assert.Falsef(t, obj.Config.IsNull(), "config should not be null")

assert.Falsef(t, obj.NodeCount.IsSpecified(), "node count should not be set")
assert.Falsef(t, obj.NodeCount.IsNull(), "node count should not be null")

assert.Falsef(t, obj.Location.IsSpecified(), "location should not be set")
assert.Falsef(t, obj.Location.IsNull(), "location should not be null")
},
},
{
name: "complex object: empty config value",
jsonInput: []byte(`{"config":{}}`),
assert: func(t *testing.T, obj ComplexNullable) {
t.Helper()

assert.Truef(t, obj.Config.IsSpecified(), "config should be set")
assert.Falsef(t, obj.Config.IsNull(), "config should not be null")

gotConfig, err := obj.Config.Get()
require.NoError(t, err)

assert.Falsef(t, gotConfig.CPU.IsSpecified(), "cpu should not be set")
assert.Falsef(t, gotConfig.CPU.IsNull(), "cpu should not be null")

assert.Falsef(t, gotConfig.RAM.IsSpecified(), "ram should not be set")
assert.Falsef(t, gotConfig.RAM.IsNull(), "ram should not be null")
},
},

{
name: "complex object: setting only cpu config value",
jsonInput: []byte(`{"config":{"cpu":"500"}}`),
assert: func(t *testing.T, obj ComplexNullable) {
t.Helper()

assert.Truef(t, obj.Config.IsSpecified(), "config should be set")
assert.Falsef(t, obj.Config.IsNull(), "config should not be null")

gotConfig, err := obj.Config.Get()
require.NoError(t, err)

assert.Truef(t, gotConfig.CPU.IsSpecified(), "cpu should be set")
assert.Falsef(t, gotConfig.CPU.IsNull(), "cpu should not be null")

assert.Falsef(t, gotConfig.RAM.IsSpecified(), "ram should not be set")
assert.Falsef(t, gotConfig.RAM.IsNull(), "ram should not be null")
},
},

{
name: "complex object: setting only ram config value",
jsonInput: []byte(`{"config":{"ram":"1024"}}`),
assert: func(t *testing.T, obj ComplexNullable) {
t.Helper()

assert.Truef(t, obj.Config.IsSpecified(), "config should be set")
assert.Falsef(t, obj.Config.IsNull(), "config should not be null")

gotConfig, err := obj.Config.Get()
require.NoError(t, err)

assert.Falsef(t, gotConfig.CPU.IsSpecified(), "cpu should not be set")
assert.Falsef(t, gotConfig.CPU.IsNull(), "cpu should not be null")

assert.Truef(t, gotConfig.RAM.IsSpecified(), "ram should be set")
assert.Falsef(t, gotConfig.RAM.IsNull(), "ram should not be null")
},
},

{
name: "complex object: setting config to null",
jsonInput: []byte(`{"config":null}`),
assert: func(t *testing.T, obj ComplexNullable) {
t.Helper()

assert.Truef(t, obj.Config.IsSpecified(), "config should be set")
assert.Truef(t, obj.Config.IsNull(), "config should not be null")
},
},

{
name: "complex object: setting only cpu config to null",
jsonInput: []byte(`{"config":{"cpu":null}}`),
assert: func(t *testing.T, obj ComplexNullable) {
t.Helper()

assert.Truef(t, obj.Config.IsSpecified(), "config should be set")
assert.Falsef(t, obj.Config.IsNull(), "config should not be null")

gotConfig, err := obj.Config.Get()
require.NoError(t, err)

assert.Truef(t, gotConfig.CPU.IsSpecified(), "cpu should be set")
assert.Truef(t, gotConfig.CPU.IsNull(), "cpu should be null")

assert.Falsef(t, gotConfig.RAM.IsSpecified(), "ram should not be set")
assert.Falsef(t, gotConfig.RAM.IsNull(), "ram should not be null")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var obj ComplexNullable
err := json.Unmarshal(tt.jsonInput, &obj)
require.NoError(t, err)

tt.assert(t, obj)
})
}
}

// Idempotency tests for nullable and optional
// Tests to validate that repeated unmarshal and marshal should not change
// the JSON for optional and nullable.
type StringNullableOptional struct {
ID nullable.Nullable[string] `json:"id,omitempty"`
Name nullable.Nullable[string] `json:"name,omitempty"`
Address nullable.Nullable[string] `json:"address,omitempty"`
}

func TestNullableOptionalUnmarshalIdempotency(t *testing.T) {
func TestNullableOptionalUnmarshal(t *testing.T) {
var obj1 StringNullableOptional
originalJSON1 := []byte(`{}`)

err := json.Unmarshal(originalJSON1, &obj1)
require.NoError(t, err)
newJSON1, err := json.Marshal(obj1)
require.NoError(t, err)

require.Equal(t, originalJSON1, newJSON1)

var obj2 StringNullableOptional
originalJSON2 := []byte(`{"id":"12esd412"}`)
err2 := json.Unmarshal(originalJSON2, &obj2)
require.NoError(t, err2)
newJSON2, err2 := json.Marshal(obj2)

err = json.Unmarshal(originalJSON2, &obj2)
require.NoError(t, err)
newJSON2, err := json.Marshal(obj2)
require.NoError(t, err)

require.Equal(t, originalJSON2, newJSON2)
}

func TestNullableOptionalMarshalIdempotency(t *testing.T) {
func TestNullableOptionalMarshal(t *testing.T) {
obj1 := StringNullableOptional{
ID: nullable.Nullable[string]{
true: "id-1",
Expand All @@ -507,8 +652,8 @@ func TestNullableOptionalMarshalIdempotency(t *testing.T) {
},
}
expectedJSON1 := []byte(`{"id":"id-1","name":"","address":null}`)
gotJSON1, err1 := json.Marshal(obj1)
require.NoError(t, err1)
gotJSON1, err := json.Marshal(obj1)
require.NoError(t, err)
require.Equal(t, expectedJSON1, gotJSON1)

obj2 := StringNullableOptional{
Expand All @@ -520,7 +665,7 @@ func TestNullableOptionalMarshalIdempotency(t *testing.T) {
},
}
expectedJSON2 := []byte(`{"id":"id-1","address":null}`)
gotJSON2, err2 := json.Marshal(obj2)
require.NoError(t, err2)
gotJSON2, err := json.Marshal(obj2)
require.NoError(t, err)
require.Equal(t, expectedJSON2, gotJSON2)
}

0 comments on commit e6e916a

Please sign in to comment.