Files
gocryptotrader/types/time_test.go
Adrian Gallagher 3cc9a2b9e0 exchanges: Refactor time handling and other minor improvements (#1948)
* exchanges: Refactor time handling and other minor improvements

- Updated Kraken wrapper to utilise new time handling methods.
- Simplified Kucoin types by removing unnecessary structures and using direct JSON unmarshalling.
- Improved websocket handling in Kucoin to directly parse candlestick data.
- Modified Lbank types to use the new time representation.
- Adjusted Poloniex wrapper and types to utilise the new time handling.
- Updated Yobit types and wrapper to reflect changes in time representation.
- Introduced DateTime type for better handling of specific time formats.
- Added tests for DateTime unmarshalling to ensure correctness.
- Rid UTC().Unix and UTC().UnixMilli as it's not needed
- Correct Huobi timestamp usage for some endpoints.
- Rid RFC3339 time parsing since Go does that automatically.

* exchanges: Refactor JSON unmarshalling for various types and improve test coverage

* linter: Update error message in TestGetKlines

* refactor: Simplify JSON unmarshalling in MovementHistory and improve test assertions in GetKlines

* refactor: Improve JSON unmarshalling for channel name and clarify comment in wsProcessOpenOrders

* refactor: Update time handling in Huobi types to use types.Time for createdAt fields and relax GetLiquidationOrders test

* refactor: Move wsTicker, wsSpread, wsTrades, and wsCandle types to kraken_types.go for better organistion

* refactor: Add validation for underlying parameter in GetExpirationTime and update tests
2025-07-01 09:11:55 +10:00

92 lines
3.0 KiB
Go

package types
import (
"strconv"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/thrasher-corp/gocryptotrader/encoding/json"
)
func TestUnmarshalJSON(t *testing.T) {
t.Parallel()
for _, tc := range []struct {
input string
want time.Time
expError error
}{
{"null", time.Time{}, nil},
{"0", time.Time{}, nil},
{`""`, time.Time{}, nil},
{`"0"`, time.Time{}, nil},
{`"0.0"`, time.Time{}, nil},
{`"0.00000"`, time.Time{}, nil},
{`"0.0.0.0"`, time.Time{}, strconv.ErrSyntax},
{`"0.1"`, time.Time{}, errInvalidTimestampFormat},
{`"1628736847"`, time.Unix(1628736847, 0), nil},
{`"1726104395.5"`, time.UnixMilli(1726104395500), nil},
{`"1726104395.56"`, time.UnixMilli(1726104395560), nil},
{`"1628736847325"`, time.UnixMilli(1628736847325), nil},
{`"1628736847325123"`, time.UnixMicro(1628736847325123), nil},
{`"1726106210903.0"`, time.UnixMicro(1726106210903000), nil},
{`"1747278712.09328"`, time.UnixMicro(1747278712093280), nil},
{`"1606292218213.4578"`, time.Unix(0, 1606292218213457800), nil},
{`"1560516023.070651"`, time.Unix(0, 1560516023070651000), nil},
{`"1606292218213457800"`, time.Unix(0, 1606292218213457800), nil},
{`"blurp"`, time.Time{}, strconv.ErrSyntax},
{`"123456"`, time.Time{}, errInvalidTimestampFormat},
{`"2025-03-28T08:00:00Z"`, time.Time{}, strconv.ErrSyntax}, // RFC3339 format
{`"1606292218213.45.8"`, time.Time{}, strconv.ErrSyntax}, // parse int failure
} {
t.Run(tc.input, func(t *testing.T) {
t.Parallel()
var testTime Time
err := json.Unmarshal([]byte(tc.input), &testTime)
require.ErrorIsf(t, err, tc.expError, "Unmarshal must not error for input %q", tc.input)
assert.Equal(t, tc.want, testTime.Time())
})
}
}
// 3948978 303.5 ns/op 168 B/op 2 allocs/op (current) after more stringent checks
// 6152384 195.5 ns/op 168 B/op 2 allocs/op (previous)
func BenchmarkUnmarshalJSON(b *testing.B) {
var testTime Time
for b.Loop() {
if err := json.Unmarshal([]byte(`"1691122380942.173000"`), &testTime); err != nil {
b.Fatal(err)
}
}
}
func TestTime(t *testing.T) {
t.Parallel()
testTime := Time(time.Time{})
assert.Equal(t, time.Time{}, testTime.Time())
assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", testTime.String())
}
func TestTime_MarshalJSON(t *testing.T) {
t.Parallel()
testTime := Time(time.Time{})
data, err := testTime.MarshalJSON()
require.NoError(t, err)
assert.Equal(t, `"0001-01-01T00:00:00Z"`, string(data))
}
func TestDateTimeUnmarshalJSON(t *testing.T) {
t.Parallel()
var (
testTime DateTime
jsonError *json.UnmarshalTypeError
parseError *time.ParseError
)
require.ErrorAs(t, json.Unmarshal([]byte(`69`), &testTime), &jsonError)
require.ErrorAs(t, json.Unmarshal([]byte(`"2025"`), &testTime), &parseError)
require.NoError(t, json.Unmarshal([]byte(`"2018-08-20 19:20:46"`), &testTime))
assert.Equal(t, time.Date(2018, 8, 20, 19, 20, 46, 0, time.UTC), testTime.Time())
}