mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-18 15:10:03 +00:00
* init * updates config * wrapper configuration * updates exchange readme * adds SendAuthHTTPRequest and SendHTTPRequest * adds ratelimit file * adds test case and minor fixes * improve error handling * update testcases and improve GetSymbols API * adds SPOT API's * minor fix * WIP * WIP * adds test case * adds check in test case * fixes in Auth. HTTP * improvements * adds trade, kline support and testcases * adds SPOT API and testcases for same * adds SPOT API and testcases * adds SPOT API and testcase * WIP * adds API's * adds API's * adds test cases * adds comment to exported data types * adds API and test cases * adds API * adds API * rearrange functions * WIP: adds API * adds API for Post Order SPOT * adds API and few fixes * fixes * WIP * WIP * add PostBulkOrder API and its test case * fix issues * adds cancel order APIs and test cases for same * add minor test fixes * add API * adds API * fixes * add API * adds API and test cases * fix test * adds API * adds test * fix test * adds API and test * adds deposit API and test cases * WIP * adds API and test cases * WIP * WIP * add public future API and test cases * WIP * remove v2 API and replace them with v1 * update test cases * adds future order API and test cases * adds futures order API * adds API * add API and test cases * adds API and test cases * adds API and test cases * adds API and test cases * Adding wrapper functions * Fix on wrapper function * Adding websocket support * Complete addressing WS push datas * Adding spot push data unit tests * adding futures websocket push data handlers * Adding futures websocket push data handlers * Added unit tests * Updating unit tests * Updating wrapper and unit test functions * Adding missing wrapper functions and code cleaning up * Resolved linter issues * Fixing websocket issues * Fixing websocket issues * Slight fix on config_example file * Minor update * Basic nits updates * Fix minor linter issues * Minor update * Minor unit test update * Minor unit test update * Code update and linter issues fix * Removed unnecessary type conversion codes * Monor update based on review comment * Fix based on review comments * Adding rate-limiter * Websocket update and overall minor fixes * Removed IsAssetTypeEnabled method implementation * Fix connection and formatting issues * Updating orderbook issues * Very minor label fix * Minor error returning fix * code cleaning up and minor spelling fix * Updates on unit test * Update on unit tests and slight code structure * unit test update * orderbook update and minor fix * fix on race * Mini linter fix * fix minor parameter and unit test issues * handler funcs and models update * Fixing websocket and unit test issues * order side string for active orders * Fix on websocket and unit tests * Minor type changes * Minor Orderbook fix and unit test update * Small fix on orderbook * Updating orderbook functionality * FIx on websocket orderbook handlers * Small update on kucoin websocket * fix missed review comments * fix based on review comments * Updating websocket orderbook and fixing unit tests * Minor fixes * unit test update * Updating unit test according to enabled asset type * toggle canManipulateRealOrders const * Unit test update * Fix minor issues * minor fix * documentation fix * wrapper coverage and unused params fix * testing and minor changes * documentation, websocket and unit test update * minor linter fix * Websocket spot/margin subscription update * minor ticker update fix * minor fixes on endpoints * timestamp and number convert method and unit tests * timestamp convert minor update * minor type and conversion fix * create a common timestamp convert and fix minor issues * linter and ticker fix * Updating unit tests and order placing endpoint methods * Added a pairs check * Fix config test error * rm unused error variable * Fix source of linter issue * code update: convert, wrapper and websocket fix * minor code update * Websocket code and unit tests update * Websocket ticker ask/bid type change and small error msg fix * docs update * fix: websocket orderbook handling * change orderbook channel to marketOrderbookLevel2Channels and fix websocket orderbook update * Minor func rename and reciever change * Minor orderbook unit test issue fix * comment: about why we used a random delimiter '-' for futures * update config files and FetchTradablePair func for futures pairs * futures config pairs update * remove ConnextionMonitorDelay from websocket setup * fix on types and futures pair conversion * updating config pairs * change NewPairFromString to DeriveFrom * unit tests update * unit tests update * Added TickerBatching * added GetStandardConfig to GetDefaultConfig --------- Co-authored-by: Jaydeep Rajpurohit <jaydeeppurohit1996@gmail.com>
486 lines
13 KiB
Go
486 lines
13 KiB
Go
package convert
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/shopspring/decimal"
|
|
)
|
|
|
|
func TestFloatFromString(t *testing.T) {
|
|
t.Parallel()
|
|
testString := "1.41421356237"
|
|
expectedOutput := float64(1.41421356237)
|
|
|
|
actualOutput, err := FloatFromString(testString)
|
|
if actualOutput != expectedOutput || err != nil {
|
|
t.Errorf("Common FloatFromString. Expected '%v'. Actual '%v'. Error: %s",
|
|
expectedOutput, actualOutput, err)
|
|
}
|
|
|
|
var testByte []byte
|
|
_, err = FloatFromString(testByte)
|
|
if err == nil {
|
|
t.Error("Common FloatFromString. Converted non-string.")
|
|
}
|
|
|
|
testString = " something unconvertible "
|
|
_, err = FloatFromString(testString)
|
|
if err == nil {
|
|
t.Error("Common FloatFromString. Converted invalid syntax.")
|
|
}
|
|
}
|
|
|
|
func TestIntFromString(t *testing.T) {
|
|
t.Parallel()
|
|
testString := "1337"
|
|
actualOutput, err := IntFromString(testString)
|
|
if expectedOutput := 1337; actualOutput != expectedOutput || err != nil {
|
|
t.Errorf("Common IntFromString. Expected '%v'. Actual '%v'. Error: %s",
|
|
expectedOutput, actualOutput, err)
|
|
}
|
|
|
|
var testByte []byte
|
|
_, err = IntFromString(testByte)
|
|
if err == nil {
|
|
t.Error("Common IntFromString. Converted non-string.")
|
|
}
|
|
|
|
testString = "1.41421356237"
|
|
_, err = IntFromString(testString)
|
|
if err == nil {
|
|
t.Error("Common IntFromString. Converted invalid syntax.")
|
|
}
|
|
}
|
|
|
|
func TestInt64FromString(t *testing.T) {
|
|
t.Parallel()
|
|
testString := "4398046511104"
|
|
expectedOutput := int64(1 << 42)
|
|
|
|
actualOutput, err := Int64FromString(testString)
|
|
if actualOutput != expectedOutput || err != nil {
|
|
t.Errorf("Common Int64FromString. Expected '%v'. Actual '%v'. Error: %s",
|
|
expectedOutput, actualOutput, err)
|
|
}
|
|
|
|
var testByte []byte
|
|
_, err = Int64FromString(testByte)
|
|
if err == nil {
|
|
t.Error("Common Int64FromString. Converted non-string.")
|
|
}
|
|
|
|
testString = "1.41421356237"
|
|
_, err = Int64FromString(testString)
|
|
if err == nil {
|
|
t.Error("Common Int64FromString. Converted invalid syntax.")
|
|
}
|
|
}
|
|
|
|
func TestTimeFromUnixTimestampFloat(t *testing.T) {
|
|
t.Parallel()
|
|
testTimestamp := float64(1414456320000)
|
|
expectedOutput := time.Date(2014, time.October, 28, 0, 32, 0, 0, time.UTC)
|
|
|
|
actualOutput, err := TimeFromUnixTimestampFloat(testTimestamp)
|
|
if actualOutput.UTC().String() != expectedOutput.UTC().String() || err != nil {
|
|
t.Errorf("Common TimeFromUnixTimestampFloat. Expected '%v'. Actual '%v'. Error: %s",
|
|
expectedOutput, actualOutput, err)
|
|
}
|
|
|
|
testString := "Time"
|
|
_, err = TimeFromUnixTimestampFloat(testString)
|
|
if err == nil {
|
|
t.Error("Common TimeFromUnixTimestampFloat. Converted invalid syntax.")
|
|
}
|
|
}
|
|
|
|
func TestTimeFromUnixTimestampDecimal(t *testing.T) {
|
|
r := TimeFromUnixTimestampDecimal(1590633982.5714)
|
|
if r.Year() != 2020 ||
|
|
r.Month().String() != "May" ||
|
|
r.Day() != 28 {
|
|
t.Error("unexpected result")
|
|
}
|
|
|
|
r = TimeFromUnixTimestampDecimal(1560516023.070651)
|
|
if r.Year() != 2019 ||
|
|
r.Month().String() != "June" ||
|
|
r.Day() != 14 {
|
|
t.Error("unexpected result")
|
|
}
|
|
}
|
|
|
|
func TestUnixTimestampToTime(t *testing.T) {
|
|
t.Parallel()
|
|
testTime := int64(1489439831)
|
|
tm := time.Unix(testTime, 0)
|
|
expectedOutput := "2017-03-13 21:17:11 +0000 UTC"
|
|
actualResult := UnixTimestampToTime(testTime)
|
|
if tm.String() != actualResult.String() {
|
|
t.Errorf(
|
|
"Expected '%s'. Actual '%s'.", expectedOutput, actualResult)
|
|
}
|
|
}
|
|
|
|
func TestUnixTimestampStrToTime(t *testing.T) {
|
|
t.Parallel()
|
|
testTime := "1489439831"
|
|
incorrectTime := "DINGDONG"
|
|
expectedOutput := "2017-03-13 21:17:11 +0000 UTC"
|
|
actualResult, err := UnixTimestampStrToTime(testTime)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if actualResult.UTC().String() != expectedOutput {
|
|
t.Errorf(
|
|
"Expected '%s'. Actual '%s'.", expectedOutput, actualResult)
|
|
}
|
|
_, err = UnixTimestampStrToTime(incorrectTime)
|
|
if err == nil {
|
|
t.Error("should throw an error")
|
|
}
|
|
}
|
|
|
|
func TestBoolPtr(t *testing.T) {
|
|
y := BoolPtr(true)
|
|
if !*y {
|
|
t.Fatal("true expected received false")
|
|
}
|
|
z := BoolPtr(false)
|
|
if *z {
|
|
t.Fatal("false expected received true")
|
|
}
|
|
}
|
|
|
|
func TestFloatToHumanFriendlyString(t *testing.T) {
|
|
t.Parallel()
|
|
test := FloatToHumanFriendlyString(0, 3, ".", ",")
|
|
if strings.Contains(test, ",") {
|
|
t.Error("unexpected ','")
|
|
}
|
|
test = FloatToHumanFriendlyString(100, 3, ".", ",")
|
|
if strings.Contains(test, ",") {
|
|
t.Error("unexpected ','")
|
|
}
|
|
test = FloatToHumanFriendlyString(1000, 3, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = FloatToHumanFriendlyString(-1000, 3, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = FloatToHumanFriendlyString(-1000, 10, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = FloatToHumanFriendlyString(1000.1337, 1, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
dec := strings.Split(test, ".")
|
|
if len(dec) == 1 {
|
|
t.Error("expected decimal place")
|
|
}
|
|
if dec[1] != "1" {
|
|
t.Error("expected decimal place")
|
|
}
|
|
}
|
|
|
|
func TestDecimalToHumanFriendlyString(t *testing.T) {
|
|
t.Parallel()
|
|
test := DecimalToHumanFriendlyString(decimal.Zero, 0, ".", ",")
|
|
if strings.Contains(test, ",") {
|
|
t.Log(test)
|
|
t.Error("unexpected ','")
|
|
}
|
|
test = DecimalToHumanFriendlyString(decimal.NewFromInt(100), 0, ".", ",")
|
|
if strings.Contains(test, ",") {
|
|
t.Log(test)
|
|
t.Error("unexpected ','")
|
|
}
|
|
test = DecimalToHumanFriendlyString(decimal.NewFromInt(1000), 0, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = DecimalToHumanFriendlyString(decimal.NewFromFloat(1000.1337), 1, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
dec := strings.Split(test, ".")
|
|
if len(dec) == 1 {
|
|
t.Error("expected decimal place")
|
|
}
|
|
if dec[1] != "1" {
|
|
t.Error("expected decimal place")
|
|
}
|
|
|
|
test = DecimalToHumanFriendlyString(decimal.NewFromFloat(-1000.1337), 1, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = DecimalToHumanFriendlyString(decimal.NewFromFloat(-1000.1337), 100000, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = DecimalToHumanFriendlyString(decimal.NewFromFloat(1000.1), 10, ".", ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
dec = strings.Split(test, ".")
|
|
if len(dec) == 1 {
|
|
t.Error("expected decimal place")
|
|
}
|
|
if dec[1] != "1" {
|
|
t.Error("expected decimal place")
|
|
}
|
|
}
|
|
|
|
func TestIntToHumanFriendlyString(t *testing.T) {
|
|
t.Parallel()
|
|
test := IntToHumanFriendlyString(0, ",")
|
|
if strings.Contains(test, ",") {
|
|
t.Log(test)
|
|
t.Error("unexpected ','")
|
|
}
|
|
test = IntToHumanFriendlyString(100, ",")
|
|
if strings.Contains(test, ",") {
|
|
t.Log(test)
|
|
t.Error("unexpected ','")
|
|
}
|
|
test = IntToHumanFriendlyString(1000, ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = IntToHumanFriendlyString(-1000, ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
|
|
test = IntToHumanFriendlyString(1000000, ",")
|
|
if !strings.Contains(test, ",") {
|
|
t.Error("expected ','")
|
|
}
|
|
dec := strings.Split(test, ",")
|
|
if len(dec) <= 2 {
|
|
t.Error("expected two commas place")
|
|
}
|
|
}
|
|
|
|
func TestNumberToHumanFriendlyString(t *testing.T) {
|
|
resp := numberToHumanFriendlyString("1", 1337, ".", ",", false)
|
|
if strings.Contains(resp, ".") {
|
|
t.Error("expected no comma")
|
|
}
|
|
}
|
|
|
|
func TestInterfaceToFloat64OrZeroValue(t *testing.T) {
|
|
var x interface{}
|
|
if r := InterfaceToFloat64OrZeroValue(x); r != 0 {
|
|
t.Errorf("expected 0, got: %v", r)
|
|
}
|
|
x = float64(420)
|
|
if r := InterfaceToFloat64OrZeroValue(x); r != 420 {
|
|
t.Errorf("expected 420, got: %v", x)
|
|
}
|
|
}
|
|
|
|
func TestInterfaceToIntOrZeroValue(t *testing.T) {
|
|
var x interface{}
|
|
if r := InterfaceToIntOrZeroValue(x); r != 0 {
|
|
t.Errorf("expected 0, got: %v", r)
|
|
}
|
|
x = int(420)
|
|
if r := InterfaceToIntOrZeroValue(x); r != 420 {
|
|
t.Errorf("expected 420, got: %v", x)
|
|
}
|
|
}
|
|
|
|
func TestInterfaceToStringOrZeroValue(t *testing.T) {
|
|
var x interface{}
|
|
if r := InterfaceToStringOrZeroValue(x); r != "" {
|
|
t.Errorf("expected empty string, got: %v", r)
|
|
}
|
|
x = string("meow")
|
|
if r := InterfaceToStringOrZeroValue(x); r != "meow" {
|
|
t.Errorf("expected meow, got: %v", x)
|
|
}
|
|
}
|
|
|
|
func TestStringToFloat64(t *testing.T) {
|
|
t.Parallel()
|
|
resp := struct {
|
|
Data StringToFloat64 `json:"data"`
|
|
}{}
|
|
|
|
err := json.Unmarshal([]byte(`{"data":"0.00000001"}`), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if resp.Data.Float64() != 1e-8 {
|
|
t.Fatalf("expected 1e-8, got %v", resp.Data.Float64())
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(`{"data":""}`), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(`{"data":1337.37}`), &resp)
|
|
if !errors.Is(err, errUnhandledType) {
|
|
t.Fatalf("received %v but expected %v", err, errUnhandledType)
|
|
}
|
|
|
|
// Demonstrates that a suffix check is not needed.
|
|
err = json.Unmarshal([]byte(`{"data":"1337.37}`), &resp)
|
|
if err == nil {
|
|
t.Fatal("error cannot be nil")
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(`{"data":"MEOW"}`), &resp)
|
|
if err == nil {
|
|
t.Fatal("error cannot be nil")
|
|
}
|
|
|
|
data, err := json.Marshal(StringToFloat64(0))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if string(data) != `""` {
|
|
t.Fatalf("expected empty string, got %v", string(data))
|
|
}
|
|
|
|
data, err = json.Marshal(StringToFloat64(1337.1337))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if string(data) != `"1337.1337"` {
|
|
t.Fatalf("expected \"1337.1337\" string, got %v", string(data))
|
|
}
|
|
}
|
|
|
|
func TestStringToFloat64Decimal(t *testing.T) {
|
|
t.Parallel()
|
|
resp := struct {
|
|
Data StringToFloat64 `json:"data"`
|
|
}{}
|
|
err := json.Unmarshal([]byte(`{"data":"0.00000001"}`), &resp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !resp.Data.Decimal().Equal(decimal.NewFromFloat(0.00000001)) {
|
|
t.Errorf("received '%v' expected '%v'", resp.Data.Decimal(), 0.00000001)
|
|
}
|
|
}
|
|
|
|
// 2677173 428.9 ns/op 240 B/op 5 allocs/op
|
|
func BenchmarkStringToFloat64(b *testing.B) {
|
|
resp := struct {
|
|
Data StringToFloat64 `json:"data"`
|
|
}{}
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
err := json.Unmarshal([]byte(`{"data":"0.00000001"}`), &resp)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestExchangeTimeUnmarshalJSON(t *testing.T) {
|
|
t.Parallel()
|
|
unmarshaledResult := &struct {
|
|
Timestamp ExchangeTime `json:"ts"`
|
|
}{}
|
|
data1 := `{"ts":""}`
|
|
result := time.Time{}
|
|
err := json.Unmarshal([]byte(data1), &unmarshaledResult)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
data2 := `{"ts":"1685564775371"}`
|
|
result = time.UnixMilli(1685564775371)
|
|
err = json.Unmarshal([]byte(data2), &unmarshaledResult)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
data3 := `{"ts":1685564775371}`
|
|
err = json.Unmarshal([]byte(data3), &unmarshaledResult)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
data4 := `{"ts":"1685564775"}`
|
|
result = time.Unix(1685564775, 0)
|
|
err = json.Unmarshal([]byte(data4), &unmarshaledResult)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
data5 := `{"ts":1685564775}`
|
|
err = json.Unmarshal([]byte(data5), &unmarshaledResult)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
data6 := `{"ts":"1685564775371320000"}`
|
|
result = time.Unix(int64(1685564775371320000)/1e9, int64(1685564775371320000)%1e9)
|
|
err = json.Unmarshal([]byte(data6), &unmarshaledResult)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
data7 := `{"ts":"abcdefg"}`
|
|
err = json.Unmarshal([]byte(data7), &unmarshaledResult)
|
|
if err == nil {
|
|
t.Fatal("expecting error but found nil")
|
|
}
|
|
data8 := `{"ts":0}`
|
|
result = time.Time{}
|
|
err = json.Unmarshal([]byte(data8), &unmarshaledResult)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
}
|
|
|
|
// 2239239 516.1 ns/op 424 B/op 9 allocs/op
|
|
func BenchmarkExchangeTimeUnmarshaling(b *testing.B) {
|
|
unmarshaledResult := &struct {
|
|
Timestamp ExchangeTime `json:"ts"`
|
|
}{}
|
|
data5 := `{"ts":1685564775}`
|
|
result := time.Unix(1685564775, 0)
|
|
var err error
|
|
for i := 0; i < b.N; i++ {
|
|
if err = json.Unmarshal([]byte(data5), &unmarshaledResult); err != nil {
|
|
b.Fatal(err)
|
|
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
|
b.Fatalf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
|
}
|
|
}
|
|
}
|