2014-08-28 17:11:18 +02:00
|
|
|
package null
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2014-08-29 03:29:17 +02:00
|
|
|
stringJSON = []byte(`"test"`)
|
|
|
|
blankStringJSON = []byte(`""`)
|
2015-09-10 13:05:24 +02:00
|
|
|
|
|
|
|
nullJSON = []byte(`null`)
|
|
|
|
invalidJSON = []byte(`:)`)
|
2014-08-28 17:11:18 +02:00
|
|
|
)
|
|
|
|
|
2014-08-29 03:29:17 +02:00
|
|
|
type stringInStruct struct {
|
|
|
|
Test String `json:"test,omitempty"`
|
|
|
|
}
|
|
|
|
|
2014-08-28 17:11:18 +02:00
|
|
|
func TestStringFrom(t *testing.T) {
|
2014-08-28 17:13:09 +02:00
|
|
|
str := StringFrom("test")
|
2014-08-30 16:53:25 +02:00
|
|
|
assertStr(t, str, "StringFrom() string")
|
2014-08-28 17:11:18 +02:00
|
|
|
|
2014-09-01 20:22:17 +02:00
|
|
|
zero := StringFrom("")
|
|
|
|
if !zero.Valid {
|
|
|
|
t.Error("StringFrom(0)", "is invalid, but should be valid")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStringFromPtr(t *testing.T) {
|
|
|
|
s := "test"
|
|
|
|
sptr := &s
|
|
|
|
str := StringFromPtr(sptr)
|
|
|
|
assertStr(t, str, "StringFromPtr() string")
|
|
|
|
|
|
|
|
null := StringFromPtr(nil)
|
|
|
|
assertNullStr(t, null, "StringFromPtr(nil)")
|
2014-08-28 17:11:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnmarshalString(t *testing.T) {
|
|
|
|
var str String
|
|
|
|
err := json.Unmarshal(stringJSON, &str)
|
|
|
|
maybePanic(err)
|
2014-08-30 16:53:25 +02:00
|
|
|
assertStr(t, str, "string json")
|
2014-08-28 17:11:18 +02:00
|
|
|
|
2014-08-29 03:29:17 +02:00
|
|
|
var blank String
|
|
|
|
err = json.Unmarshal(blankStringJSON, &blank)
|
|
|
|
maybePanic(err)
|
2015-10-02 07:42:03 +02:00
|
|
|
if !blank.Valid {
|
|
|
|
t.Error("blank string should be valid")
|
|
|
|
}
|
2014-08-29 03:29:17 +02:00
|
|
|
|
2014-08-28 17:11:18 +02:00
|
|
|
var null String
|
|
|
|
err = json.Unmarshal(nullJSON, &null)
|
|
|
|
maybePanic(err)
|
2014-08-30 16:53:25 +02:00
|
|
|
assertNullStr(t, null, "null json")
|
2014-09-09 05:31:58 +02:00
|
|
|
|
|
|
|
var badType String
|
|
|
|
err = json.Unmarshal(boolJSON, &badType)
|
|
|
|
if err == nil {
|
|
|
|
panic("err should not be nil")
|
|
|
|
}
|
|
|
|
assertNullStr(t, badType, "wrong type json")
|
2015-09-10 13:05:24 +02:00
|
|
|
|
|
|
|
var invalid String
|
|
|
|
err = invalid.UnmarshalJSON(invalidJSON)
|
|
|
|
if _, ok := err.(*json.SyntaxError); !ok {
|
|
|
|
t.Errorf("expected json.SyntaxError, not %T", err)
|
|
|
|
}
|
|
|
|
assertNullStr(t, invalid, "invalid json")
|
2014-08-28 17:11:18 +02:00
|
|
|
}
|
|
|
|
|
2014-08-29 03:50:02 +02:00
|
|
|
func TestTextUnmarshalString(t *testing.T) {
|
|
|
|
var str String
|
|
|
|
err := str.UnmarshalText([]byte("test"))
|
|
|
|
maybePanic(err)
|
2014-08-30 16:53:25 +02:00
|
|
|
assertStr(t, str, "UnmarshalText() string")
|
2014-08-29 03:50:02 +02:00
|
|
|
|
|
|
|
var null String
|
|
|
|
err = null.UnmarshalText([]byte(""))
|
|
|
|
maybePanic(err)
|
2014-08-30 16:53:25 +02:00
|
|
|
assertNullStr(t, null, "UnmarshalText() empty string")
|
2014-08-29 03:50:02 +02:00
|
|
|
}
|
|
|
|
|
2014-08-28 17:11:18 +02:00
|
|
|
func TestMarshalString(t *testing.T) {
|
2014-08-28 17:13:09 +02:00
|
|
|
str := StringFrom("test")
|
2014-08-28 17:11:18 +02:00
|
|
|
data, err := json.Marshal(str)
|
|
|
|
maybePanic(err)
|
|
|
|
assertJSONEquals(t, data, `"test"`, "non-empty json marshal")
|
2016-02-28 01:53:16 +01:00
|
|
|
data, err = str.MarshalText()
|
|
|
|
maybePanic(err)
|
|
|
|
assertJSONEquals(t, data, "test", "non-empty text marshal")
|
2014-08-28 17:11:18 +02:00
|
|
|
|
2014-09-01 20:22:17 +02:00
|
|
|
// empty values should be encoded as an empty string
|
|
|
|
zero := StringFrom("")
|
|
|
|
data, err = json.Marshal(zero)
|
2014-08-28 17:11:18 +02:00
|
|
|
maybePanic(err)
|
2014-08-29 03:29:17 +02:00
|
|
|
assertJSONEquals(t, data, `""`, "empty json marshal")
|
2016-02-28 01:53:16 +01:00
|
|
|
data, err = zero.MarshalText()
|
|
|
|
maybePanic(err)
|
|
|
|
assertJSONEquals(t, data, "", "string marshal text")
|
2014-09-01 20:22:17 +02:00
|
|
|
|
|
|
|
null := StringFromPtr(nil)
|
|
|
|
data, err = json.Marshal(null)
|
|
|
|
maybePanic(err)
|
|
|
|
assertJSONEquals(t, data, `null`, "null json marshal")
|
2016-02-28 01:53:16 +01:00
|
|
|
data, err = null.MarshalText()
|
|
|
|
maybePanic(err)
|
|
|
|
assertJSONEquals(t, data, "", "string marshal text")
|
2014-08-28 17:11:18 +02:00
|
|
|
}
|
|
|
|
|
2014-08-29 03:29:17 +02:00
|
|
|
// Tests omitempty... broken until Go 1.4
|
|
|
|
// func TestMarshalStringInStruct(t *testing.T) {
|
|
|
|
// obj := stringInStruct{Test: StringFrom("")}
|
|
|
|
// data, err := json.Marshal(obj)
|
|
|
|
// maybePanic(err)
|
|
|
|
// assertJSONEquals(t, data, `{}`, "null string in struct")
|
|
|
|
// }
|
|
|
|
|
2014-08-30 16:53:25 +02:00
|
|
|
func TestStringPointer(t *testing.T) {
|
2014-08-28 17:13:09 +02:00
|
|
|
str := StringFrom("test")
|
2014-08-31 10:28:34 +02:00
|
|
|
ptr := str.Ptr()
|
2014-08-28 17:11:18 +02:00
|
|
|
if *ptr != "test" {
|
|
|
|
t.Errorf("bad %s string: %#v ≠ %s\n", "pointer", ptr, "test")
|
|
|
|
}
|
|
|
|
|
2014-09-01 20:22:17 +02:00
|
|
|
null := NewString("", false)
|
2014-08-31 10:28:34 +02:00
|
|
|
ptr = null.Ptr()
|
|
|
|
if ptr != nil {
|
|
|
|
t.Errorf("bad %s string: %#v ≠ %s\n", "nil pointer", ptr, "nil")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-06 20:14:43 +02:00
|
|
|
func TestStringIsNull(t *testing.T) {
|
2014-08-28 17:37:35 +02:00
|
|
|
str := StringFrom("test")
|
2017-07-06 20:14:43 +02:00
|
|
|
if str.IsNull() {
|
|
|
|
t.Errorf("IsNull() should be false")
|
2014-08-28 17:37:35 +02:00
|
|
|
}
|
|
|
|
|
2014-09-01 20:22:17 +02:00
|
|
|
blank := StringFrom("")
|
2017-07-06 20:14:43 +02:00
|
|
|
if blank.IsNull() {
|
|
|
|
t.Errorf("IsNull() should be false")
|
2014-08-28 17:37:35 +02:00
|
|
|
}
|
2014-08-29 04:09:04 +02:00
|
|
|
|
|
|
|
empty := NewString("", true)
|
2017-07-06 20:14:43 +02:00
|
|
|
if empty.IsNull() {
|
|
|
|
t.Errorf("IsNull() should be false")
|
2014-09-01 20:22:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
null := StringFromPtr(nil)
|
2017-07-06 20:14:43 +02:00
|
|
|
if !null.IsNull() {
|
|
|
|
t.Errorf("IsNull() should be true")
|
|
|
|
}
|
|
|
|
|
|
|
|
var testInt interface{}
|
|
|
|
testInt = empty
|
|
|
|
if _, ok := testInt.(Nullable); !ok {
|
|
|
|
t.Errorf("Nullable interface should be implemented")
|
2014-08-29 04:09:04 +02:00
|
|
|
}
|
2014-08-28 17:37:35 +02:00
|
|
|
}
|
|
|
|
|
2014-09-01 20:22:17 +02:00
|
|
|
func TestStringSetValid(t *testing.T) {
|
|
|
|
change := NewString("", false)
|
|
|
|
assertNullStr(t, change, "SetValid()")
|
|
|
|
change.SetValid("test")
|
|
|
|
assertStr(t, change, "SetValid()")
|
|
|
|
}
|
|
|
|
|
2014-08-30 16:53:25 +02:00
|
|
|
func TestStringScan(t *testing.T) {
|
2014-08-28 17:11:18 +02:00
|
|
|
var str String
|
|
|
|
err := str.Scan("test")
|
|
|
|
maybePanic(err)
|
2014-08-30 16:53:25 +02:00
|
|
|
assertStr(t, str, "scanned string")
|
2014-08-28 17:11:18 +02:00
|
|
|
|
|
|
|
var null String
|
|
|
|
err = null.Scan(nil)
|
|
|
|
maybePanic(err)
|
2014-08-30 16:53:25 +02:00
|
|
|
assertNullStr(t, null, "scanned null")
|
2014-08-28 17:11:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func maybePanic(err error) {
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-30 16:53:25 +02:00
|
|
|
func assertStr(t *testing.T, s String, from string) {
|
2014-08-28 17:11:18 +02:00
|
|
|
if s.String != "test" {
|
|
|
|
t.Errorf("bad %s string: %s ≠ %s\n", from, s.String, "test")
|
|
|
|
}
|
|
|
|
if !s.Valid {
|
|
|
|
t.Error(from, "is invalid, but should be valid")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-30 16:53:25 +02:00
|
|
|
func assertNullStr(t *testing.T, s String, from string) {
|
2014-08-28 17:11:18 +02:00
|
|
|
if s.Valid {
|
|
|
|
t.Error(from, "is valid, but should be invalid")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func assertJSONEquals(t *testing.T, data []byte, cmp string, from string) {
|
|
|
|
if string(data) != cmp {
|
|
|
|
t.Errorf("bad %s data: %s ≠ %s\n", from, data, cmp)
|
|
|
|
}
|
|
|
|
}
|