|
package optional_test |
|
|
|
import ( |
|
"database/sql" |
|
"encoding/json" |
|
"fmt" |
|
"testing" |
|
|
|
"github.com/org/repo/optional" |
|
) |
|
|
|
func TestString(t *testing.T) { |
|
t.Parallel() |
|
|
|
type expect struct { |
|
value string |
|
null bool |
|
set bool |
|
omitted bool |
|
json string |
|
} |
|
|
|
tests := []struct { |
|
description string |
|
in string |
|
expect expect |
|
}{ |
|
{ |
|
description: "omitted value", |
|
in: `{}`, |
|
expect: expect{value: "", null: false, set: false, omitted: true, json: `{"name":""}`}, |
|
}, |
|
{ |
|
description: "null value", |
|
in: `{"name":null}`, |
|
expect: expect{value: "", null: true, set: true, omitted: false, json: `{"name":null}`}, |
|
}, |
|
{ |
|
description: "empty value", |
|
in: `{"name":""}`, |
|
expect: expect{value: "", null: false, set: true, omitted: false, json: `{"name":""}`}, |
|
}, |
|
{ |
|
description: "non-empty value", |
|
in: `{"name":"Bob"}`, |
|
expect: expect{value: "Bob", null: false, set: true, omitted: false, json: `{"name":"Bob"}`}, |
|
}, |
|
} |
|
|
|
for _, tc := range tests { |
|
t.Run(tc.description, func(t *testing.T) { |
|
p := struct { |
|
Name optional.String `json:"name,omitempty"` |
|
}{} |
|
|
|
err := json.Unmarshal([]byte(tc.in), &p) |
|
if err != nil { |
|
t.Error("Expected err to be nil:", err) |
|
} |
|
|
|
if p.Name.Value != tc.expect.value { |
|
t.Error("Expected Value to be", tc.expect.value, "but got", p.Name.Value) |
|
} |
|
|
|
if p.Name.Null != tc.expect.null { |
|
t.Error("Expected IsNull to be", tc.expect.null) |
|
} |
|
|
|
if p.Name.Set != tc.expect.set { |
|
t.Error("Expected IsSet to be", tc.expect.null) |
|
} |
|
|
|
if p.Name.Omitted() != tc.expect.omitted { |
|
t.Error("Expected Omitted to be", tc.expect.omitted) |
|
} |
|
|
|
out, err := json.Marshal(p) |
|
if err != nil { |
|
t.Error("Expected err to be nil:", err) |
|
} |
|
|
|
if string(out) != tc.expect.json { |
|
t.Error("Expected json output to be:", tc.expect.json, ", got:", string(out)) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func TestNewString(t *testing.T) { |
|
t.Parallel() |
|
|
|
type expect struct { |
|
value string |
|
null bool |
|
set bool |
|
omitted bool |
|
} |
|
|
|
tests := []struct { |
|
description string |
|
in string |
|
expect expect |
|
}{ |
|
{ |
|
description: "empty value", |
|
in: "", |
|
expect: expect{value: "", null: false, set: true, omitted: false}, |
|
}, |
|
{ |
|
description: "non-empty value", |
|
in: "Bob", |
|
expect: expect{value: "Bob", null: false, set: true, omitted: false}, |
|
}, |
|
} |
|
|
|
for _, tc := range tests { |
|
t.Run(tc.description, func(t *testing.T) { |
|
out := optional.NewString(tc.in) |
|
|
|
if out.Value != tc.expect.value { |
|
t.Error("Expected Value to be", tc.expect.value, "but got", out.Value) |
|
} |
|
|
|
if out.Null != tc.expect.null { |
|
t.Error("Expected IsNull to be", tc.expect.null) |
|
} |
|
|
|
if out.Set != tc.expect.set { |
|
t.Error("Expected IsSet to be", tc.expect.null) |
|
} |
|
|
|
if out.Omitted() != tc.expect.omitted { |
|
t.Error("Expected Omitted to be", tc.expect.omitted) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func TestString_ToNullString(t *testing.T) { |
|
t.Parallel() |
|
|
|
tests := []struct { |
|
description string |
|
in optional.String |
|
expect sql.NullString |
|
}{ |
|
{ |
|
description: "omitted value", |
|
in: optional.String{Value: "", Null: false, Set: false}, |
|
expect: sql.NullString{Valid: false, String: ""}, |
|
}, |
|
{ |
|
description: "null value", |
|
in: optional.String{Value: "", Null: true, Set: false}, |
|
expect: sql.NullString{Valid: false, String: ""}, |
|
}, |
|
{ |
|
description: "null value set", |
|
in: optional.String{Value: "", Null: true, Set: true}, |
|
expect: sql.NullString{Valid: false, String: ""}, |
|
}, |
|
{ |
|
description: "empty value", |
|
in: optional.String{Value: "", Null: false, Set: true}, |
|
expect: sql.NullString{Valid: true, String: ""}, |
|
}, |
|
{ |
|
description: "non-empty value", |
|
in: optional.String{Value: "Bob", Null: false, Set: true}, |
|
expect: sql.NullString{Valid: true, String: "Bob"}, |
|
}, |
|
} |
|
|
|
for _, tc := range tests { |
|
t.Run(tc.description, func(t *testing.T) { |
|
if tc.in.ToNullString().String != tc.expect.String { |
|
t.Error("Expected String to be", tc.expect.String, "but got", tc.in.ToNullString().String) |
|
} |
|
|
|
if tc.in.ToNullString().Valid != tc.expect.Valid { |
|
t.Error("Expected Valid to be", tc.expect.Valid) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func ExampleString() { |
|
type PersonRequest struct { |
|
Name optional.String `json:"name"` |
|
NickName optional.String `json:"nick_name"` |
|
HomeTown optional.String `json:"home_town,omitempty"` |
|
FavoriteAuthor optional.String `json:"favorite_author"` |
|
} |
|
|
|
var p PersonRequest |
|
|
|
json.Unmarshal([]byte(`{"name":"Robert", "nick_name":null, "favorite_author":""}`), &p) |
|
|
|
fmt.Printf("Name: Set %v, Null %v, Omitted %v\n", p.Name.Set, p.Name.Null, p.Name.Omitted()) |
|
fmt.Printf("NickName: Set %v, Null %v, Omitted %v\n", p.NickName.Set, p.NickName.Null, p.NickName.Omitted()) |
|
fmt.Printf("HomeTown: Set %v, Null %v, Omitted %v\n", p.HomeTown.Set, p.HomeTown.Null, p.HomeTown.Omitted()) |
|
fmt.Printf("FavoriteAuthor: Set %v, Null %v, Omitted %v\n", p.FavoriteAuthor.Set, p.FavoriteAuthor.Null, p.FavoriteAuthor.Omitted()) |
|
|
|
// Output: |
|
// Name: Set true, Null false, Omitted false |
|
// NickName: Set true, Null true, Omitted false |
|
// HomeTown: Set false, Null false, Omitted true |
|
// FavoriteAuthor: Set true, Null false, Omitted false |
|
} |
|
|
|
func ExampleString_MarshalJSON() { |
|
type PersonRequest struct { |
|
Name optional.String `json:"name"` |
|
NickName optional.String `json:"nick_name"` |
|
HomeTown optional.String `json:"home_town,omitempty"` |
|
FavoriteAuthor optional.String `json:"favorite_author"` |
|
} |
|
|
|
p := PersonRequest{ |
|
Name: optional.NewString("Robert"), |
|
NickName: optional.String{Value: "", Null: true, Set: true}, |
|
FavoriteAuthor: optional.NewString(""), |
|
} |
|
|
|
data, err := json.Marshal(&p) |
|
|
|
fmt.Printf("Data is: %s\n", data) |
|
fmt.Printf("Error is: %v\n", err) |
|
|
|
// Output: |
|
// Data is: {"name":"Robert","nick_name":null,"home_town":"","favorite_author":""} |
|
// Error is: <nil> |
|
} |