Skip to content

Commit 9485159

Browse files
author
Jeff Schroeder
committed
Addding full coverage for PythPriceComponent
1 parent 9cff231 commit 9485159

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

pythclient/pythaccounts.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,10 @@ def __iter__(self):
401401
yield key, val
402402

403403

404-
class PythPriceComponent: # This has the individual prices each publisher
404+
class PythPriceComponent:
405405
"""
406-
Represents a price component.
406+
Represents a price component. This is the individual prices each
407+
publisher sends in addition to their aggregate.
407408
408409
Attributes:
409410
publisher_key (SolanaPublicKey): the public key of the publisher
@@ -443,6 +444,12 @@ def deserialise(buffer: bytes, offset: int = 0, *, exponent: int) -> Optional[Py
443444
latest_price = PythPriceInfo.deserialise(buffer, offset, exponent=exponent)
444445
return PythPriceComponent(key, last_aggregate_price, latest_price, exponent)
445446

447+
def __iter__(self):
448+
for key, val in self.__dict__.items():
449+
if isinstance(val, PythPriceInfo):
450+
val = dict(val)
451+
yield key, val
452+
446453

447454
class PythPriceAccount(PythAccount):
448455
"""

tests/test_price_component.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import pytest
2+
3+
from pythclient.solana import SolanaPublicKey
4+
from pythclient.pythaccounts import PythPriceComponent, PythPriceInfo, PythPriceStatus
5+
6+
7+
@pytest.fixture
8+
def price_component_bytes() -> bytes:
9+
return bytes(
10+
[
11+
247, 102, 125, 187, 141, 124, 211, 23, 33, 137, 65, 74, 35,
12+
194, 107, 82, 29, 140, 25, 198, 69, 4, 85, 85, 227, 226, 142,
13+
130, 86, 142, 101, 120, 224, 123, 2, 167, 14, 0, 0, 0, 32, 197,
14+
251, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 211, 177, 79, 6, 0,
15+
0, 0, 0, 224, 123, 2, 167, 14, 0, 0, 0, 32, 197, 251, 0, 0, 0,
16+
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 212, 177, 79, 6, 0, 0, 0, 0,
17+
]
18+
)
19+
20+
21+
@pytest.fixture
22+
def price_component():
23+
exponent = -8
24+
publisher_key = SolanaPublicKey("HekM1hBawXQu6wK6Ah1yw1YXXeMUDD2bfCHEzo25vnEB")
25+
last_aggregate_price = PythPriceInfo(**{
26+
'raw_price': 62931500000,
27+
'raw_confidence_interval': 16500000,
28+
'price_status': PythPriceStatus.TRADING,
29+
'slot': 105886163,
30+
'exponent': exponent,
31+
})
32+
latest_price = PythPriceInfo(**{
33+
'raw_price': 62931500000,
34+
'raw_confidence_interval': 16500000,
35+
'price_status': PythPriceStatus.TRADING,
36+
'slot': 105886164,
37+
'exponent': exponent,
38+
})
39+
return PythPriceComponent(
40+
publisher_key,
41+
last_aggregate_price_info=last_aggregate_price,
42+
latest_price_info=latest_price,
43+
exponent=exponent,
44+
)
45+
46+
47+
def test_valid_deserialise(price_component, price_component_bytes):
48+
actual = PythPriceComponent.deserialise(price_component_bytes, exponent=price_component.exponent)
49+
50+
# To make pyright happy
51+
assert actual is not None
52+
53+
# Make the actual assertions
54+
assert dict(actual) == dict(price_component)
55+
56+
57+
def test_deserialise_null_publisher_key(price_component, price_component_bytes):
58+
# Zero out the solana key (the first 32 bytes of the buffer)
59+
bad_bytes = bytes(b'\x00' * SolanaPublicKey.LENGTH) + price_component_bytes[SolanaPublicKey.LENGTH:]
60+
actual = PythPriceComponent.deserialise(bad_bytes, exponent=price_component.exponent)
61+
assert actual is None

0 commit comments

Comments
 (0)