Files
gocryptotrader/exchanges/order/order_test.go
Andrew 40122b3094 (CLI) Fix getorders command currency pair filtering (#400)
* add currency pair filtering to getorders

* long live the Queen

* fixed wording on tests
2019-12-18 09:12:58 +11:00

537 lines
13 KiB
Go

package order
import (
"errors"
"strings"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/currency"
)
func TestValidate(t *testing.T) {
testPair := currency.NewPair(currency.BTC, currency.LTC)
tester := []struct {
Pair currency.Pair
Side
Type
Amount float64
Price float64
ExpectedErr error
}{
{
ExpectedErr: ErrPairIsEmpty,
}, // empty pair
{
Pair: testPair,
ExpectedErr: ErrSideIsInvalid,
}, // valid pair but invalid order side
{
Pair: testPair,
Side: Buy,
ExpectedErr: ErrTypeIsInvalid,
}, // valid pair and order side but invalid order type
{
Pair: testPair,
Side: Sell,
ExpectedErr: ErrTypeIsInvalid,
}, // valid pair and order side but invalid order type
{
Pair: testPair,
Side: Bid,
ExpectedErr: ErrTypeIsInvalid,
}, // valid pair and order side but invalid order type
{
Pair: testPair,
Side: Ask,
ExpectedErr: ErrTypeIsInvalid,
}, // valid pair and order side but invalid order type
{
Pair: testPair,
Side: Ask,
Type: Market,
ExpectedErr: ErrAmountIsInvalid,
}, // valid pair, order side, type but invalid amount
{
Pair: testPair,
Side: Ask,
Type: Limit,
Amount: 1,
ExpectedErr: ErrPriceMustBeSetIfLimitOrder,
}, // valid pair, order side, type, amount but invalid price
{
Pair: testPair,
Side: Ask,
Type: Limit,
Amount: 1,
Price: 1000,
ExpectedErr: nil,
}, // valid order!
}
for x := range tester {
s := Submit{
Pair: tester[x].Pair,
OrderSide: tester[x].Side,
OrderType: tester[x].Type,
Amount: tester[x].Amount,
Price: tester[x].Price,
}
if err := s.Validate(); err != tester[x].ExpectedErr {
t.Errorf("Unexpected result. Got: %s, want: %s", err, tester[x].ExpectedErr)
}
}
}
func TestOrderSides(t *testing.T) {
t.Parallel()
var os = Buy
if os.String() != "BUY" {
t.Errorf("unexpected string %s", os.String())
}
if os.Lower() != "buy" {
t.Errorf("unexpected string %s", os.String())
}
}
func TestOrderTypes(t *testing.T) {
t.Parallel()
var ot Type = "Mo'Money"
if ot.String() != "Mo'Money" {
t.Errorf("unexpected string %s", ot.String())
}
if ot.Lower() != "mo'money" {
t.Errorf("unexpected string %s", ot.Lower())
}
}
func TestFilterOrdersByType(t *testing.T) {
t.Parallel()
var orders = []Detail{
{
OrderType: ImmediateOrCancel,
},
{
OrderType: Limit,
},
}
FilterOrdersByType(&orders, AnyType)
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
FilterOrdersByType(&orders, Limit)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
FilterOrdersByType(&orders, Stop)
if len(orders) != 0 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
func TestFilterOrdersBySide(t *testing.T) {
t.Parallel()
var orders = []Detail{
{
OrderSide: Buy,
},
{
OrderSide: Sell,
},
{},
}
FilterOrdersBySide(&orders, AnySide)
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
FilterOrdersBySide(&orders, Buy)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
FilterOrdersBySide(&orders, Sell)
if len(orders) != 0 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
func TestFilterOrdersByTickRange(t *testing.T) {
t.Parallel()
var orders = []Detail{
{
OrderDate: time.Unix(100, 0),
},
{
OrderDate: time.Unix(110, 0),
},
{
OrderDate: time.Unix(111, 0),
},
}
FilterOrdersByTickRange(&orders, time.Unix(0, 0), time.Unix(0, 0))
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
FilterOrdersByTickRange(&orders, time.Unix(100, 0), time.Unix(111, 0))
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
FilterOrdersByTickRange(&orders, time.Unix(101, 0), time.Unix(111, 0))
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
FilterOrdersByTickRange(&orders, time.Unix(200, 0), time.Unix(300, 0))
if len(orders) != 0 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
func TestFilterOrdersByCurrencies(t *testing.T) {
t.Parallel()
var orders = []Detail{
{
CurrencyPair: currency.NewPair(currency.BTC, currency.USD),
},
{
CurrencyPair: currency.NewPair(currency.LTC, currency.EUR),
},
{
CurrencyPair: currency.NewPair(currency.DOGE, currency.RUB),
},
}
currencies := []currency.Pair{currency.NewPair(currency.BTC, currency.USD),
currency.NewPair(currency.LTC, currency.EUR),
currency.NewPair(currency.DOGE, currency.RUB)}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
currencies = []currency.Pair{currency.NewPair(currency.BTC, currency.USD),
currency.NewPair(currency.LTC, currency.EUR)}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
currencies = []currency.Pair{currency.NewPair(currency.BTC, currency.USD)}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
currencies = []currency.Pair{}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
}
func TestSortOrdersByPrice(t *testing.T) {
t.Parallel()
orders := []Detail{
{
Price: 100,
}, {
Price: 0,
}, {
Price: 50,
},
}
SortOrdersByPrice(&orders, false)
if orders[0].Price != 0 {
t.Errorf("Expected: '%v', received: '%v'", 0, orders[0].Price)
}
SortOrdersByPrice(&orders, true)
if orders[0].Price != 100 {
t.Errorf("Expected: '%v', received: '%v'", 100, orders[0].Price)
}
}
func TestSortOrdersByDate(t *testing.T) {
t.Parallel()
orders := []Detail{
{
OrderDate: time.Unix(0, 0),
}, {
OrderDate: time.Unix(1, 0),
}, {
OrderDate: time.Unix(2, 0),
},
}
SortOrdersByDate(&orders, false)
if orders[0].OrderDate.Unix() != time.Unix(0, 0).Unix() {
t.Errorf("Expected: '%v', received: '%v'",
time.Unix(0, 0).Unix(),
orders[0].OrderDate.Unix())
}
SortOrdersByDate(&orders, true)
if orders[0].OrderDate.Unix() != time.Unix(2, 0).Unix() {
t.Errorf("Expected: '%v', received: '%v'",
time.Unix(2, 0).Unix(),
orders[0].OrderDate.Unix())
}
}
func TestSortOrdersByCurrency(t *testing.T) {
t.Parallel()
orders := []Detail{
{
CurrencyPair: currency.NewPairWithDelimiter(currency.BTC.String(),
currency.USD.String(),
"-"),
}, {
CurrencyPair: currency.NewPairWithDelimiter(currency.DOGE.String(),
currency.USD.String(),
"-"),
}, {
CurrencyPair: currency.NewPairWithDelimiter(currency.BTC.String(),
currency.RUB.String(),
"-"),
}, {
CurrencyPair: currency.NewPairWithDelimiter(currency.LTC.String(),
currency.EUR.String(),
"-"),
}, {
CurrencyPair: currency.NewPairWithDelimiter(currency.LTC.String(),
currency.AUD.String(),
"-"),
},
}
SortOrdersByCurrency(&orders, false)
if orders[0].CurrencyPair.String() != currency.BTC.String()+"-"+currency.RUB.String() {
t.Errorf("Expected: '%v', received: '%v'",
currency.BTC.String()+"-"+currency.RUB.String(),
orders[0].CurrencyPair.String())
}
SortOrdersByCurrency(&orders, true)
if orders[0].CurrencyPair.String() != currency.LTC.String()+"-"+currency.EUR.String() {
t.Errorf("Expected: '%v', received: '%v'",
currency.LTC.String()+"-"+currency.EUR.String(),
orders[0].CurrencyPair.String())
}
}
func TestSortOrdersByOrderSide(t *testing.T) {
t.Parallel()
orders := []Detail{
{
OrderSide: Buy,
}, {
OrderSide: Sell,
}, {
OrderSide: Sell,
}, {
OrderSide: Buy,
},
}
SortOrdersBySide(&orders, false)
if !strings.EqualFold(orders[0].OrderSide.String(), Buy.String()) {
t.Errorf("Expected: '%v', received: '%v'",
Buy,
orders[0].OrderSide)
}
SortOrdersBySide(&orders, true)
if !strings.EqualFold(orders[0].OrderSide.String(), Sell.String()) {
t.Errorf("Expected: '%v', received: '%v'",
Sell,
orders[0].OrderSide)
}
}
func TestSortOrdersByOrderType(t *testing.T) {
t.Parallel()
orders := []Detail{
{
OrderType: Market,
}, {
OrderType: Limit,
}, {
OrderType: ImmediateOrCancel,
}, {
OrderType: TrailingStop,
},
}
SortOrdersByType(&orders, false)
if !strings.EqualFold(orders[0].OrderType.String(), ImmediateOrCancel.String()) {
t.Errorf("Expected: '%v', received: '%v'",
ImmediateOrCancel,
orders[0].OrderType)
}
SortOrdersByType(&orders, true)
if !strings.EqualFold(orders[0].OrderType.String(), TrailingStop.String()) {
t.Errorf("Expected: '%v', received: '%v'",
TrailingStop,
orders[0].OrderType)
}
}
var stringsToOrderSide = []struct {
in string
out Side
err error
}{
{"buy", Buy, nil},
{"BUY", Buy, nil},
{"bUy", Buy, nil},
{"sell", Sell, nil},
{"SELL", Sell, nil},
{"sElL", Sell, nil},
{"bid", Bid, nil},
{"BID", Bid, nil},
{"bId", Bid, nil},
{"ask", Ask, nil},
{"ASK", Ask, nil},
{"aSk", Ask, nil},
{"any", AnySide, nil},
{"ANY", AnySide, nil},
{"aNy", AnySide, nil},
{"woahMan", Buy, errors.New("woahMan not recognised as side type")},
}
func TestStringToOrderSide(t *testing.T) {
for i := 0; i < len(stringsToOrderSide); i++ {
testData := &stringsToOrderSide[i]
t.Run(testData.in, func(t *testing.T) {
out, err := StringToOrderSide(testData.in)
if err != nil {
if err.Error() != testData.err.Error() {
t.Error("Unexpected error", err)
}
} else if out != testData.out {
t.Errorf("Unexpected output %v. Expected %v", out, testData.out)
}
})
}
}
var stringsToOrderType = []struct {
in string
out Type
err error
}{
{"limit", Limit, nil},
{"LIMIT", Limit, nil},
{"lImIt", Limit, nil},
{"market", Market, nil},
{"MARKET", Market, nil},
{"mArKeT", Market, nil},
{"immediate_or_cancel", ImmediateOrCancel, nil},
{"IMMEDIATE_OR_CANCEL", ImmediateOrCancel, nil},
{"iMmEdIaTe_Or_CaNcEl", ImmediateOrCancel, nil},
{"stop", Stop, nil},
{"STOP", Stop, nil},
{"sToP", Stop, nil},
{"trailingstop", TrailingStop, nil},
{"TRAILINGSTOP", TrailingStop, nil},
{"tRaIlInGsToP", TrailingStop, nil},
{"any", AnyType, nil},
{"ANY", AnyType, nil},
{"aNy", AnyType, nil},
{"woahMan", Unknown, errors.New("woahMan not recognised as order type")},
}
func TestStringToOrderType(t *testing.T) {
for i := 0; i < len(stringsToOrderType); i++ {
testData := &stringsToOrderType[i]
t.Run(testData.in, func(t *testing.T) {
out, err := StringToOrderType(testData.in)
if err != nil {
if err.Error() != testData.err.Error() {
t.Error("Unexpected error", err)
}
} else if out != testData.out {
t.Errorf("Unexpected output %v. Expected %v", out, testData.out)
}
})
}
}
var stringsToOrderStatus = []struct {
in string
out Status
err error
}{
{"any", AnyStatus, nil},
{"ANY", AnyStatus, nil},
{"aNy", AnyStatus, nil},
{"new", New, nil},
{"NEW", New, nil},
{"nEw", New, nil},
{"active", Active, nil},
{"ACTIVE", Active, nil},
{"aCtIvE", Active, nil},
{"partially_filled", PartiallyFilled, nil},
{"PARTIALLY_FILLED", PartiallyFilled, nil},
{"pArTiAlLy_FiLlEd", PartiallyFilled, nil},
{"filled", Filled, nil},
{"FILLED", Filled, nil},
{"fIlLeD", Filled, nil},
{"cancelled", Cancelled, nil},
{"CANCELlED", Cancelled, nil},
{"cAnCellEd", Cancelled, nil},
{"pending_cancel", PendingCancel, nil},
{"PENDING_CANCEL", PendingCancel, nil},
{"pENdInG_cAnCeL", PendingCancel, nil},
{"rejected", Rejected, nil},
{"REJECTED", Rejected, nil},
{"rEjEcTeD", Rejected, nil},
{"expired", Expired, nil},
{"EXPIRED", Expired, nil},
{"eXpIrEd", Expired, nil},
{"hidden", Hidden, nil},
{"HIDDEN", Hidden, nil},
{"hIdDeN", Hidden, nil},
{"woahMan", UnknownStatus, errors.New("woahMan not recognised as order STATUS")},
}
func TestStringToOrderStatus(t *testing.T) {
for i := 0; i < len(stringsToOrderStatus); i++ {
testData := &stringsToOrderStatus[i]
t.Run(testData.in, func(t *testing.T) {
out, err := StringToOrderStatus(testData.in)
if err != nil {
if err.Error() != testData.err.Error() {
t.Error("Unexpected error", err)
}
} else if out != testData.out {
t.Errorf("Unexpected output %v. Expected %v", out, testData.out)
}
})
}
}