305 lines
5.1 KiB
Go
305 lines
5.1 KiB
Go
package hrana
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func toPtr[T any](v T) *T {
|
|
return &v
|
|
}
|
|
|
|
func TestValueToValue(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
columnType string
|
|
value Value
|
|
want any
|
|
}{
|
|
{
|
|
name: "null",
|
|
value: Value{
|
|
Type: "null",
|
|
Value: nil,
|
|
},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "int",
|
|
value: Value{
|
|
Type: "integer",
|
|
Value: strconv.FormatInt(int64(42), 10),
|
|
},
|
|
want: int64(42),
|
|
},
|
|
{
|
|
name: "string",
|
|
value: Value{
|
|
Type: "text",
|
|
Value: "foo",
|
|
},
|
|
want: "foo",
|
|
},
|
|
{
|
|
name: "bytes",
|
|
value: Value{
|
|
Type: "blob",
|
|
Base64: toPtr("YmFy"),
|
|
},
|
|
want: []byte("bar"),
|
|
},
|
|
{
|
|
name: "bytes",
|
|
value: Value{
|
|
Type: "blob",
|
|
Base64: toPtr(""),
|
|
},
|
|
want: []byte{},
|
|
},
|
|
{
|
|
name: "float",
|
|
value: Value{
|
|
Type: "float",
|
|
Value: 3.14,
|
|
},
|
|
want: 3.14,
|
|
},
|
|
{
|
|
name: "timestamp",
|
|
columnType: "TIMESTAMP",
|
|
value: Value{
|
|
Type: "text",
|
|
Value: "0001-01-01 01:00:00+00:00",
|
|
},
|
|
want: time.Time{}.Add(time.Hour),
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
var columnType *string = nil
|
|
if tt.columnType != "" {
|
|
columnType = &tt.columnType
|
|
}
|
|
got := tt.value.ToValue(columnType)
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("ToValue() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToValue(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
value any
|
|
want Value
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "null",
|
|
value: nil,
|
|
want: Value{
|
|
Type: "null",
|
|
},
|
|
},
|
|
{
|
|
name: "int",
|
|
value: 42,
|
|
want: Value{
|
|
Type: "integer",
|
|
Value: strconv.FormatInt(int64(42), 10),
|
|
},
|
|
},
|
|
{
|
|
name: "string",
|
|
value: "foo",
|
|
want: Value{
|
|
Type: "text",
|
|
Value: "foo",
|
|
},
|
|
},
|
|
{
|
|
name: "bytes",
|
|
value: []byte{},
|
|
want: Value{
|
|
Type: "blob",
|
|
Base64: toPtr(""),
|
|
},
|
|
},
|
|
{
|
|
name: "float",
|
|
value: 3.14,
|
|
want: Value{
|
|
Type: "float",
|
|
Value: 3.14,
|
|
},
|
|
},
|
|
{
|
|
name: "boolean",
|
|
value: true,
|
|
want: Value{
|
|
Type: "integer",
|
|
Value: "1",
|
|
},
|
|
},
|
|
{
|
|
name: "timestamp",
|
|
value: time.Time{}.Add(time.Hour),
|
|
want: Value{
|
|
Type: "text",
|
|
Value: "0001-01-01 01:00:00+00:00",
|
|
},
|
|
},
|
|
{
|
|
name: "unsupported",
|
|
value: make(chan int),
|
|
want: Value{},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := ToValue(tt.value)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("ToValue() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("ToValue() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMarshal(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
value Value
|
|
marshaled string
|
|
}{
|
|
{
|
|
name: "null",
|
|
value: Value{
|
|
Type: "null",
|
|
},
|
|
marshaled: `{"type":"null"}`,
|
|
},
|
|
{
|
|
name: "int",
|
|
value: Value{
|
|
Type: "integer",
|
|
Value: strconv.FormatInt(int64(42), 10),
|
|
},
|
|
marshaled: `{"type":"integer","value":"42"}`,
|
|
},
|
|
{
|
|
name: "string",
|
|
value: Value{
|
|
Type: "text",
|
|
Value: "foo",
|
|
},
|
|
marshaled: `{"type":"text","value":"foo"}`,
|
|
},
|
|
{
|
|
name: "bytes",
|
|
value: Value{
|
|
Type: "blob",
|
|
Base64: toPtr("YmFy"),
|
|
},
|
|
marshaled: `{"type":"blob","base64":"YmFy"}`,
|
|
},
|
|
{
|
|
name: "float",
|
|
value: Value{
|
|
Type: "float",
|
|
Value: 3.14,
|
|
},
|
|
marshaled: `{"type":"float","value":3.14}`,
|
|
},
|
|
{
|
|
name: "timestamp",
|
|
value: Value{
|
|
Type: "text",
|
|
Value: time.Time{}.Add(time.Hour),
|
|
},
|
|
marshaled: `{"type":"text","value":"0001-01-01T01:00:00Z"}`,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := json.Marshal(tt.value)
|
|
if err != nil {
|
|
t.Errorf("json.Marshal() error = %v", err)
|
|
return
|
|
}
|
|
if !reflect.DeepEqual(string(got), tt.marshaled) {
|
|
t.Errorf("json.Marshal() = %v, want %v", string(got), tt.marshaled)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUnmarshal(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
value Value
|
|
marshaled string
|
|
}{
|
|
{
|
|
name: "null",
|
|
value: Value{
|
|
Type: "null",
|
|
},
|
|
marshaled: `{"type":"null"}`,
|
|
},
|
|
{
|
|
name: "int",
|
|
value: Value{
|
|
Type: "integer",
|
|
Value: strconv.FormatInt(int64(42), 10),
|
|
},
|
|
marshaled: `{"type":"integer","value":"42"}`,
|
|
},
|
|
{
|
|
name: "string",
|
|
value: Value{
|
|
Type: "text",
|
|
Value: "foo",
|
|
},
|
|
marshaled: `{"type":"text","value":"foo"}`,
|
|
},
|
|
{
|
|
name: "bytes",
|
|
value: Value{
|
|
Type: "blob",
|
|
Base64: toPtr("YmFy"),
|
|
},
|
|
marshaled: `{"type":"blob","base64":"YmFy"}`,
|
|
},
|
|
{
|
|
name: "float",
|
|
value: Value{
|
|
Type: "float",
|
|
Value: 3.14,
|
|
},
|
|
marshaled: `{"type":"float","value":3.14}`,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
var got Value
|
|
err := json.Unmarshal([]byte(tt.marshaled), &got)
|
|
if err != nil {
|
|
t.Errorf("json.Marshal() error = %v", err)
|
|
return
|
|
}
|
|
if !reflect.DeepEqual(got, tt.value) {
|
|
t.Errorf("json.Unmarshal() = %v, want %v", got, tt.value)
|
|
}
|
|
})
|
|
}
|
|
}
|