mirror of
https://github.com/aljazceru/bitfinex-api-py.git
synced 2025-12-18 22:34:21 +01:00
Add tests subpackage. Add TestRestSerializersAndTypes and TestWebsocketSerializersAndTypes unit tests. Fix consistency bugs between serializers and types.
This commit is contained in:
@@ -28,6 +28,9 @@ class _Serializer(Generic[T]):
|
||||
def parse(self, *values: Any, skip: Optional[List[str]] = None) -> T:
|
||||
return cast(T, self.klass(**dict(self._serialize(*values, skip=skip))))
|
||||
|
||||
def get_labels(self) -> List[str]:
|
||||
return [ label for label in self.__labels if label not in self.__IGNORE ]
|
||||
|
||||
class _RecursiveSerializer(_Serializer, Generic[T]):
|
||||
def __init__(self, name: str, klass: Type[_Type], labels: List[str], serializers: Dict[str, _Serializer[Any]], IGNORE: List[str] = ["_PLACEHOLDER"]):
|
||||
super().__init__(name, klass, labels, IGNORE)
|
||||
|
||||
@@ -4,6 +4,26 @@ from .. labeler import generate_labeler_serializer, generate_recursive_serialize
|
||||
|
||||
from .. notification import _Notification
|
||||
|
||||
__serializers__ = [
|
||||
"PlatformStatus", "TradingPairTicker", "FundingCurrencyTicker",
|
||||
"TickersHistory", "TradingPairTrade", "FundingCurrencyTrade",
|
||||
"TradingPairBook", "FundingCurrencyBook", "TradingPairRawBook",
|
||||
"FundingCurrencyRawBook", "Statistic", "Candle",
|
||||
"DerivativesStatus", "Liquidation", "Leaderboard",
|
||||
"FundingStatistic", "PulseProfile", "PulseMessage",
|
||||
"TradingMarketAveragePrice", "FundingMarketAveragePrice", "FxRate",
|
||||
|
||||
"Order", "Position", "Trade",
|
||||
"FundingTrade", "OrderTrade", "Ledger",
|
||||
"FundingOffer", "FundingCredit", "FundingLoan",
|
||||
"FundingAutoRenew", "FundingInfo", "Wallet",
|
||||
"Transfer", "Withdrawal", "DepositAddress",
|
||||
"Invoice", "Movement", "SymbolMarginInfo",
|
||||
"BaseMarginInfo", "Claim", "IncreaseInfo",
|
||||
"Increase", "PositionHistory", "PositionSnapshot",
|
||||
"PositionAudit", "DerivativePositionCollateral", "DerivativePositionCollateralLimits",
|
||||
]
|
||||
|
||||
#region Serializers definition for Rest Public Endpoints
|
||||
|
||||
PlatformStatus = generate_labeler_serializer("PlatformStatus", klass=types.PlatformStatus, labels=[
|
||||
@@ -308,7 +328,7 @@ Position = generate_labeler_serializer("Position", klass=types.Position, labels=
|
||||
|
||||
Trade = generate_labeler_serializer("Trade", klass=types.Trade, labels=[
|
||||
"id",
|
||||
"pair",
|
||||
"symbol",
|
||||
"mts_create",
|
||||
"order_id",
|
||||
"exec_amount",
|
||||
@@ -333,7 +353,7 @@ FundingTrade = generate_labeler_serializer("FundingTrade", klass=types.FundingTr
|
||||
|
||||
OrderTrade = generate_labeler_serializer("OrderTrade", klass=types.OrderTrade, labels=[
|
||||
"id",
|
||||
"pair",
|
||||
"symbol",
|
||||
"mts_create",
|
||||
"order_id",
|
||||
"exec_amount",
|
||||
|
||||
@@ -6,12 +6,32 @@ from .. labeler import _Type
|
||||
from .. notification import Notification
|
||||
from .. utils.encoder import JSON
|
||||
|
||||
__types__ = [
|
||||
"PlatformStatus", "TradingPairTicker", "FundingCurrencyTicker",
|
||||
"TickersHistory", "TradingPairTrade", "FundingCurrencyTrade",
|
||||
"TradingPairBook", "FundingCurrencyBook", "TradingPairRawBook",
|
||||
"FundingCurrencyRawBook", "Statistic", "Candle",
|
||||
"DerivativesStatus", "Liquidation", "Leaderboard",
|
||||
"FundingStatistic", "PulseProfile", "PulseMessage",
|
||||
"TradingMarketAveragePrice", "FundingMarketAveragePrice", "FxRate",
|
||||
|
||||
"Order", "Position", "Trade",
|
||||
"FundingTrade", "OrderTrade", "Ledger",
|
||||
"FundingOffer", "FundingCredit", "FundingLoan",
|
||||
"FundingAutoRenew", "FundingInfo", "Wallet",
|
||||
"Transfer", "Withdrawal", "DepositAddress",
|
||||
"Invoice", "Movement", "SymbolMarginInfo",
|
||||
"BaseMarginInfo", "Claim", "IncreaseInfo",
|
||||
"Increase", "PositionHistory", "PositionSnapshot",
|
||||
"PositionAudit", "DerivativePositionCollateral", "DerivativePositionCollateralLimits",
|
||||
]
|
||||
|
||||
#region Type hinting for Rest Public Endpoints
|
||||
|
||||
@dataclass
|
||||
class PlatformStatus(_Type):
|
||||
status: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class TradingPairTicker(_Type):
|
||||
symbol: Optional[str]
|
||||
|
||||
8
bfxapi/tests/__init__.py
Normal file
8
bfxapi/tests/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import unittest
|
||||
from .test_rest_serializers_and_types import TestRestSerializersAndTypes
|
||||
from .test_websocket_serializers_and_types import TestWebsocketSerializersAndTypes
|
||||
|
||||
NAME = "tests"
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
23
bfxapi/tests/test_rest_serializers_and_types.py
Normal file
23
bfxapi/tests/test_rest_serializers_and_types.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import unittest
|
||||
|
||||
from ..rest import serializers, types
|
||||
|
||||
class TestRestSerializersAndTypes(unittest.TestCase):
|
||||
def test_consistency(self):
|
||||
__types__ = list(map(types.__dict__.get, types.__types__))
|
||||
|
||||
for serializer in map(serializers.__dict__.get, serializers.__serializers__):
|
||||
type = types.__dict__.get(serializer.name)
|
||||
|
||||
__types__.remove(type)
|
||||
self.assertIsNotNone(type, f"_Serializer <{serializer.name}>: no respective _Type found in bfxapi.rest.types.")
|
||||
self.assertEqual(serializer.klass, type, f"_Serializer <{serializer.name}>.klass: field does not match with respective _Type in bfxapi.rest.types.")
|
||||
|
||||
self.assertListEqual(serializer.get_labels(), list(type.__annotations__),
|
||||
f"_Serializer <{serializer.name}> and _Type <{type.__name__}> must have matching labels and fields.")
|
||||
|
||||
for type in __types__:
|
||||
self.fail(f"_Type <{type.__name__}>: no respective _Serializer found in bfxapi.rest.serializers.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
23
bfxapi/tests/test_websocket_serializers_and_types.py
Normal file
23
bfxapi/tests/test_websocket_serializers_and_types.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import unittest
|
||||
|
||||
from ..websocket import serializers, types
|
||||
|
||||
class TestWebsocketSerializersAndTypes(unittest.TestCase):
|
||||
def test_consistency(self):
|
||||
__types__ = list(map(types.__dict__.get, types.__types__))
|
||||
|
||||
for serializer in map(serializers.__dict__.get, serializers.__serializers__):
|
||||
type = types.__dict__.get(serializer.name)
|
||||
|
||||
__types__.remove(type)
|
||||
self.assertIsNotNone(type, f"_Serializer <{serializer.name}>: no respective _Type found in bfxapi.websocket.types.")
|
||||
self.assertEqual(serializer.klass, type, f"_Serializer <{serializer.name}>.klass: field does not match with respective _Type in bfxapi.websocket.types.")
|
||||
|
||||
self.assertListEqual(serializer.get_labels(), list(type.__annotations__),
|
||||
f"_Serializer <{serializer.name}> and _Type <{type.__name__}> must have matching labels and fields.")
|
||||
|
||||
for type in __types__:
|
||||
self.fail(f"_Type <{type.__name__}>: no respective _Serializer found in bfxapi.websocket.serializers.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -4,6 +4,17 @@ from .. labeler import generate_labeler_serializer
|
||||
|
||||
from .. notification import _Notification
|
||||
|
||||
__serializers__ = [
|
||||
"TradingPairTicker", "FundingCurrencyTicker", "TradingPairTrade",
|
||||
"FundingCurrencyTrade", "TradingPairBook", "FundingCurrencyBook",
|
||||
"TradingPairRawBook", "FundingCurrencyRawBook", "Candle",
|
||||
"DerivativesStatus",
|
||||
|
||||
"Order", "Position", "Trade",
|
||||
"FundingOffer", "FundingCredit", "FundingLoan",
|
||||
"Wallet", "Balance",
|
||||
]
|
||||
|
||||
#region Serializers definition for Websocket Public Channels
|
||||
|
||||
TradingPairTicker = generate_labeler_serializer("TradingPairTicker", klass=types.TradingPairTicker, labels=[
|
||||
@@ -32,7 +43,7 @@ FundingCurrencyTicker = generate_labeler_serializer("FundingCurrencyTicker", kla
|
||||
"last_price",
|
||||
"volume",
|
||||
"high",
|
||||
"low"
|
||||
"low",
|
||||
"_PLACEHOLDER",
|
||||
"_PLACEHOLDER",
|
||||
"frr_amount_available"
|
||||
@@ -100,7 +111,7 @@ DerivativesStatus = generate_labeler_serializer("DerivativesStatus", klass=types
|
||||
"next_funding_accrued",
|
||||
"next_funding_step",
|
||||
"_PLACEHOLDER",
|
||||
"current_funding"
|
||||
"current_funding",
|
||||
"_PLACEHOLDER",
|
||||
"_PLACEHOLDER",
|
||||
"mark_price",
|
||||
|
||||
@@ -6,6 +6,17 @@ from ..labeler import _Type
|
||||
from ..notification import Notification
|
||||
from .. utils.encoder import JSON
|
||||
|
||||
__types__ = [
|
||||
"TradingPairTicker", "FundingCurrencyTicker", "TradingPairTrade",
|
||||
"FundingCurrencyTrade", "TradingPairBook", "FundingCurrencyBook",
|
||||
"TradingPairRawBook", "FundingCurrencyRawBook", "Candle",
|
||||
"DerivativesStatus",
|
||||
|
||||
"Order", "Position", "Trade",
|
||||
"FundingOffer", "FundingCredit", "FundingLoan",
|
||||
"Wallet", "Balance",
|
||||
]
|
||||
|
||||
#region Type hinting for Websocket Public Channels
|
||||
|
||||
@dataclass
|
||||
@@ -143,6 +154,7 @@ class Position(_Type):
|
||||
pl_perc: float
|
||||
price_liq: float
|
||||
leverage: float
|
||||
flag: int
|
||||
position_id: int
|
||||
mts_create: int
|
||||
mts_update: int
|
||||
|
||||
Reference in New Issue
Block a user