From 899914c40cd4e87867171a526e222b72fb06461c Mon Sep 17 00:00:00 2001 From: ko_oler <kooler89@gmail.com> Date: Tue, 22 Aug 2023 16:45:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D0=9F=D0=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/schema/field/timestamp.go | 49 +++++++++++-------------- pkg/schema/field/timestamp_test.go | 57 +++++++++++++++++------------- 2 files changed, 52 insertions(+), 54 deletions(-) diff --git a/pkg/schema/field/timestamp.go b/pkg/schema/field/timestamp.go index cbe95923..7626639a 100644 --- a/pkg/schema/field/timestamp.go +++ b/pkg/schema/field/timestamp.go @@ -5,8 +5,6 @@ import ( "fmt" "reflect" "time" - - "git.perx.ru/perxis/perxis-go/pkg/errors" ) var timestampType = &TimestampType{} @@ -31,31 +29,25 @@ func (TimestampType) IsEmpty(v interface{}) bool { } func (TimestampType) Decode(_ context.Context, _ *Field, v interface{}) (interface{}, error) { - if v == nil { - return nil, nil - } - switch i := v.(type) { + case nil: + return 0, nil case string: duration, err := time.ParseDuration(i) - if err != nil { - t, err := time.Parse(time.TimeOnly, i) - if err != nil { - return nil, errors.Wrap(err, "wrong format") - } + if err == nil { + return duration.Nanoseconds(), nil + } + t, err := time.Parse(time.TimeOnly, i) + if err == nil { return t.Sub(time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())).Nanoseconds(), nil } - return duration.Nanoseconds(), nil + return nil, err default: - v, err := ToInt(i) - if err != nil { - return nil, fmt.Errorf("TimestampField decode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind()) - } - return v, nil + return toTimestamp(i) } } -func ToInt(i interface{}) (interface{}, error) { +func toTimestamp(i interface{}) (interface{}, error) { switch v := i.(type) { case int64: return v, nil @@ -66,26 +58,25 @@ func ToInt(i interface{}) (interface{}, error) { case int32: return int64(v), nil case uint64: - return v, nil + return int64(v), nil case uint: - return uint64(v), nil + return int64(v), nil case uint8: - return uint64(v), nil + return int64(v), nil case uint32: - return uint64(v), nil + return int64(v), nil default: - return 0, errors.Errorf("error convert \"%s\" to timestamp", i) + return 0, fmt.Errorf("unsupported value type: \"%s\"", reflect.ValueOf(v).Kind()) } } func (TimestampType) Encode(_ context.Context, _ *Field, v interface{}) (interface{}, error) { - if v == nil { - return nil, nil - } - if _, ok := v.(int64); ok { - return v, nil + switch i := v.(type) { + case nil: + return 0, nil + default: + return toTimestamp(i) } - return nil, fmt.Errorf("TimestampField encode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind()) } func Timestamp(o ...interface{}) *Field { diff --git a/pkg/schema/field/timestamp_test.go b/pkg/schema/field/timestamp_test.go index 94be768b..67be1abb 100644 --- a/pkg/schema/field/timestamp_test.go +++ b/pkg/schema/field/timestamp_test.go @@ -4,6 +4,8 @@ import ( "context" "reflect" "testing" + + "github.com/stretchr/testify/require" ) func TestTimestamp_Decode(t *testing.T) { @@ -13,31 +15,34 @@ func TestTimestamp_Decode(t *testing.T) { data interface{} want interface{} wantErr bool + errMsg string }{ - {"Correct", Timestamp(), int64(2), int64(2), false}, // #0 - {"Correct", Timestamp(), uint64(2), uint64(2), false}, // #1 - {"Correct", Timestamp(), 2, int64(2), false}, // #2 - {"Correct", Timestamp(), "13h10m44s", int64(47444000000000), false}, // #3 - {"Correct", Timestamp(), "24h", int64(86400000000000), false}, // #4 - {"Correct", Timestamp(), "2.5h", int64(9000000000000), false}, // #5 - {"Correct", Timestamp(), "-5h", int64(-18000000000000), false}, // #5 - {"Correct", Timestamp(), "13:10:44", int64(47444000000000), false}, // #6 - {"Correct", Timestamp(), "23:59:59", int64(86399000000000), false}, // #7 - {"Correct", Timestamp(), "00:00:00", int64(0), false}, // #8 - {"Correct", Timestamp(), "00:00:01", int64(1000000000), false}, // #8 + {"Correct", Timestamp(), int64(2), int64(2), false, ""}, // #0 + {"Correct", Timestamp(), int32(2), int64(2), false, ""}, // #1 + {"Correct", Timestamp(), 2, int64(2), false, ""}, // #2 + {"Correct", Timestamp(), "13h10m44s", int64(47444000000000), false, ""}, // #3 + {"Correct", Timestamp(), "24h", int64(86400000000000), false, ""}, // #4 + {"Correct", Timestamp(), "2.5h", int64(9000000000000), false, ""}, // #5 + {"Correct", Timestamp(), "-5h", int64(-18000000000000), false, ""}, // #5 + {"Correct", Timestamp(), "13:10:44", int64(47444000000000), false, ""}, // #6 + {"Correct", Timestamp(), "23:59:59", int64(86399000000000), false, ""}, // #7 + {"Correct", Timestamp(), "00:00:00", int64(0), false, ""}, // #8 + {"Correct", Timestamp(), "00:00:01", int64(1000000000), false, ""}, // #8 + {"Correct", Timestamp(), uint64(2), int64(2), false, ""}, + {"Correct", Timestamp(), nil, 0, false, ""}, - {"Wrong data", Timestamp(), "", nil, true}, // #0 - {"Wrong data", Timestamp(), []byte(""), nil, true}, // #1 - {"Wrong data", Timestamp(), 2.2, nil, true}, // #2 - {"Wrong data", Timestamp(), "13:10", nil, true}, // #3 - {"Wrong data", Timestamp(), "24:00:00", nil, true}, // #4 + {"Wrong data", Timestamp(), "", nil, true, "decode error: parsing time \"\" as \"15:04:05\": cannot parse \"\" as \"15\""}, // #0 + {"Wrong data", Timestamp(), []byte(""), nil, true, "decode error: unsupported value type: \"slice\""}, // #1 + {"Wrong data", Timestamp(), 2.2, nil, true, "decode error: unsupported value type: \"float64\""}, // #2 + {"Wrong data", Timestamp(), "13:10", nil, true, "decode error: parsing time \"13:10\" as \"15:04:05\": cannot parse \"\" as \":\""}, // #3 + {"Wrong data", Timestamp(), "24:00:00", nil, true, "decode error: parsing time \"24:00:00\": hour out of range"}, // #4 } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := Decode(context.Background(), tt.field, tt.data) - if (err != nil) != tt.wantErr { - t.Errorf("Decode() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Equal(t, tt.errMsg, err.Error()) return } if !reflect.DeepEqual(got, tt.want) { @@ -54,20 +59,22 @@ func TestTimestamp_Encode(t *testing.T) { data interface{} want interface{} wantErr bool + errMsg string }{ - {"Correct", Timestamp(), int64(2), int64(2), false}, // #0 + {"Correct", Timestamp(), int64(2), int64(2), false, ""}, // #0 + {"Correct", Timestamp(), 2, int64(2), false, ""}, // #1 + {"Correct", Timestamp(), uint64(2), int64(2), false, ""}, // #2 - {"Wrong data", Timestamp(), "", nil, true}, // #0 - {"Wrong data", Timestamp(), []byte(""), nil, true}, // #1 - {"Wrong data", Timestamp(), 2.2, nil, true}, // #2 - {"Wrong data", Timestamp(), uint64(2), nil, true}, // #2 + {"Wrong data", Timestamp(), "", nil, true, "encode error: unsupported value type: \"string\""}, // #0 + {"Wrong data", Timestamp(), []byte(""), nil, true, "encode error: unsupported value type: \"slice\""}, // #1 + {"Wrong data", Timestamp(), 2.2, nil, true, "encode error: unsupported value type: \"float64\""}, // #2 } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := Encode(context.Background(), tt.field, tt.data) - if (err != nil) != tt.wantErr { - t.Errorf("Decode() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Equal(t, tt.errMsg, err.Error()) return } if !reflect.DeepEqual(got, tt.want) { -- GitLab