mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-26 23:59:58 -07:00
python: fix tests
This commit is contained in:
@@ -12,9 +12,9 @@ def test_client_creation():
|
||||
|
||||
def test_tree_exists():
|
||||
client = BrkClient("http://localhost:3110")
|
||||
assert hasattr(client, "metrics")
|
||||
assert hasattr(client.metrics, "price")
|
||||
assert hasattr(client.metrics, "blocks")
|
||||
assert hasattr(client, "series")
|
||||
assert hasattr(client.series, "prices")
|
||||
assert hasattr(client.series, "blocks")
|
||||
|
||||
|
||||
def test_fetch_block():
|
||||
@@ -22,38 +22,38 @@ def test_fetch_block():
|
||||
print(client.get_block_by_height(800000))
|
||||
|
||||
|
||||
def test_fetch_json_metric():
|
||||
def test_fetch_json_series():
|
||||
client = BrkClient("http://localhost:3110")
|
||||
a = client.get_metric("price_close", "day1")
|
||||
a = client.get_series("price_close", "day1")
|
||||
print(a)
|
||||
|
||||
|
||||
def test_fetch_csv_metric():
|
||||
def test_fetch_csv_series():
|
||||
client = BrkClient("http://localhost:3110")
|
||||
a = client.get_metric("price_close", "day1", -10, None, None, "csv")
|
||||
a = client.get_series("price_close", "day1", -10, None, None, "csv")
|
||||
print(a)
|
||||
|
||||
|
||||
def test_fetch_typed_metric():
|
||||
def test_fetch_typed_series():
|
||||
client = BrkClient("http://localhost:3110")
|
||||
# Using new idiomatic API: tail(10).fetch() or [-10:].fetch()
|
||||
a = client.metrics.constants._0.by.day1().tail(10).fetch()
|
||||
a = client.series.constants._0.by.day1().tail(10).fetch()
|
||||
print(a)
|
||||
b = client.metrics.outputs.count.unspent.by.height().tail(10).fetch()
|
||||
b = client.series.outputs.count.unspent.by.height().tail(10).fetch()
|
||||
print(b)
|
||||
c = client.metrics.prices.split.close.usd.by.day1().tail(10).fetch()
|
||||
c = client.series.prices.split.close.usd.by.day1().tail(10).fetch()
|
||||
print(c)
|
||||
d = (
|
||||
client.metrics.market.dca.period.lump_sum_stack._10y.usd.by.day1()
|
||||
client.series.market.dca.period.lump_sum_stack._10y.usd.by.day1()
|
||||
.tail(10)
|
||||
.fetch()
|
||||
)
|
||||
print(d)
|
||||
e = (
|
||||
client.metrics.market.dca.class_.cost_basis.from_2017.usd.by.day1()
|
||||
client.series.market.dca.class_.cost_basis.from_2017.usd.by.day1()
|
||||
.tail(10)
|
||||
.fetch()
|
||||
)
|
||||
print(e)
|
||||
f = client.metrics.prices.ohlc.usd.by.day1().tail(10).fetch()
|
||||
f = client.series.prices.ohlc.usd.by.day1().tail(10).fetch()
|
||||
print(f)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Tests for MetricData and DateMetricData helper methods including polars/pandas conversion
|
||||
# Tests for SeriesData and DateSeriesData helper methods including polars/pandas conversion
|
||||
# Run: uv run pytest tests/test_metric_data.py -v
|
||||
|
||||
from datetime import date, datetime, timezone, timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
from brk_client import MetricData, DateMetricData
|
||||
from brk_client import SeriesData, DateSeriesData
|
||||
|
||||
|
||||
# ============ Fixtures ============
|
||||
@@ -13,10 +13,11 @@ from brk_client import MetricData, DateMetricData
|
||||
|
||||
@pytest.fixture
|
||||
def day1_metric():
|
||||
"""DateMetricData with day1 (date-based, daily)."""
|
||||
return DateMetricData(
|
||||
"""DateSeriesData with day1 (date-based, daily)."""
|
||||
return DateSeriesData(
|
||||
version=1,
|
||||
index="day1",
|
||||
type="n",
|
||||
total=100,
|
||||
start=0,
|
||||
end=5,
|
||||
@@ -27,10 +28,11 @@ def day1_metric():
|
||||
|
||||
@pytest.fixture
|
||||
def height_metric():
|
||||
"""MetricData with height (non-date-based)."""
|
||||
return MetricData(
|
||||
"""SeriesData with height (non-date-based)."""
|
||||
return SeriesData(
|
||||
version=1,
|
||||
index="height",
|
||||
type="n",
|
||||
total=1000,
|
||||
start=800000,
|
||||
end=800005,
|
||||
@@ -41,10 +43,11 @@ def height_metric():
|
||||
|
||||
@pytest.fixture
|
||||
def month1_metric():
|
||||
"""DateMetricData with month1."""
|
||||
return DateMetricData(
|
||||
"""DateSeriesData with month1."""
|
||||
return DateSeriesData(
|
||||
version=1,
|
||||
index="month1",
|
||||
type="n",
|
||||
total=200,
|
||||
start=0,
|
||||
end=3,
|
||||
@@ -55,10 +58,11 @@ def month1_metric():
|
||||
|
||||
@pytest.fixture
|
||||
def hour1_metric():
|
||||
"""DateMetricData with hour1 (sub-daily)."""
|
||||
return DateMetricData(
|
||||
"""DateSeriesData with hour1 (sub-daily)."""
|
||||
return DateSeriesData(
|
||||
version=1,
|
||||
index="hour1",
|
||||
type="n",
|
||||
total=200000,
|
||||
start=0,
|
||||
end=3,
|
||||
@@ -69,10 +73,11 @@ def hour1_metric():
|
||||
|
||||
@pytest.fixture
|
||||
def week1_metric():
|
||||
"""DateMetricData with week1."""
|
||||
return DateMetricData(
|
||||
"""DateSeriesData with week1."""
|
||||
return DateSeriesData(
|
||||
version=1,
|
||||
index="week1",
|
||||
type="n",
|
||||
total=800,
|
||||
start=0,
|
||||
end=3,
|
||||
@@ -83,10 +88,11 @@ def week1_metric():
|
||||
|
||||
@pytest.fixture
|
||||
def year1_metric():
|
||||
"""DateMetricData with year1."""
|
||||
return DateMetricData(
|
||||
"""DateSeriesData with year1."""
|
||||
return DateSeriesData(
|
||||
version=1,
|
||||
index="year1",
|
||||
type="n",
|
||||
total=20,
|
||||
start=0,
|
||||
end=3,
|
||||
@@ -97,10 +103,11 @@ def year1_metric():
|
||||
|
||||
@pytest.fixture
|
||||
def day3_metric():
|
||||
"""DateMetricData with day3."""
|
||||
return DateMetricData(
|
||||
"""DateSeriesData with day3."""
|
||||
return DateSeriesData(
|
||||
version=1,
|
||||
index="day3",
|
||||
type="n",
|
||||
total=2000,
|
||||
start=0,
|
||||
end=3,
|
||||
@@ -111,10 +118,11 @@ def day3_metric():
|
||||
|
||||
@pytest.fixture
|
||||
def empty_metric():
|
||||
"""MetricData with empty data."""
|
||||
return MetricData(
|
||||
"""SeriesData with empty data."""
|
||||
return SeriesData(
|
||||
version=1,
|
||||
index="day1",
|
||||
type="n",
|
||||
total=100,
|
||||
start=5,
|
||||
end=5,
|
||||
@@ -149,10 +157,10 @@ class TestIsDateBased:
|
||||
assert height_metric.is_date_based is False
|
||||
|
||||
|
||||
# ============ MetricData (int-indexed) ============
|
||||
# ============ SeriesData (int-indexed) ============
|
||||
|
||||
|
||||
class TestMetricData:
|
||||
class TestSeriesData:
|
||||
def test_keys(self, height_metric):
|
||||
assert height_metric.keys() == [800000, 800001, 800002, 800003, 800004]
|
||||
|
||||
@@ -192,13 +200,13 @@ class TestMetricData:
|
||||
assert empty_metric.indexes() == []
|
||||
|
||||
|
||||
# ============ DateMetricData inheritance ============
|
||||
# ============ DateSeriesData inheritance ============
|
||||
|
||||
|
||||
class TestDateMetricDataInheritance:
|
||||
class TestDateSeriesDataInheritance:
|
||||
def test_isinstance(self, day1_metric):
|
||||
assert isinstance(day1_metric, DateMetricData)
|
||||
assert isinstance(day1_metric, MetricData)
|
||||
assert isinstance(day1_metric, DateSeriesData)
|
||||
assert isinstance(day1_metric, SeriesData)
|
||||
|
||||
def test_int_keys_inherited(self, day1_metric):
|
||||
assert day1_metric.keys() == [0, 1, 2, 3, 4]
|
||||
@@ -363,10 +371,10 @@ class TestDateToIndex:
|
||||
assert _date_to_index("hour1", d) == i
|
||||
|
||||
|
||||
# ============ DateMetricData date methods ============
|
||||
# ============ DateSeriesData date methods ============
|
||||
|
||||
|
||||
class TestDateMetricDataMethods:
|
||||
class TestDateSeriesDataMethods:
|
||||
def test_date_items(self, day1_metric):
|
||||
items = day1_metric.date_items()
|
||||
assert items[0] == (date(2009, 1, 3), 100)
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
from brk_client import BrkClient
|
||||
|
||||
|
||||
def is_metric_pattern(obj):
|
||||
"""Check if an object is a metric pattern (has indexes() method and by attribute)."""
|
||||
def is_series_pattern(obj):
|
||||
"""Check if an object is a series pattern (has indexes() method and by attribute)."""
|
||||
return (
|
||||
hasattr(obj, "indexes")
|
||||
and callable(getattr(obj, "indexes", None))
|
||||
@@ -15,9 +15,9 @@ def is_metric_pattern(obj):
|
||||
)
|
||||
|
||||
|
||||
def get_all_metrics(obj, path=""):
|
||||
"""Recursively collect all MetricPattern instances from the tree."""
|
||||
metrics = []
|
||||
def get_all_series(obj, path=""):
|
||||
"""Recursively collect all SeriesPattern instances from the tree."""
|
||||
series = []
|
||||
|
||||
for attr_name in dir(obj):
|
||||
# Skip dunder methods and internal attributes (_letter), but allow _digit (e.g., _10y, _2017)
|
||||
@@ -36,43 +36,43 @@ def get_all_metrics(obj, path=""):
|
||||
|
||||
current_path = f"{path}.{attr_name}" if path else attr_name
|
||||
|
||||
# Check if this is a metric pattern using the indexes() method
|
||||
if is_metric_pattern(attr):
|
||||
metrics.append((current_path, attr))
|
||||
# Check if this is a series pattern using the indexes() method
|
||||
if is_series_pattern(attr):
|
||||
series.append((current_path, attr))
|
||||
|
||||
# Recurse into nested tree nodes
|
||||
if hasattr(attr, "__dict__"):
|
||||
metrics.extend(get_all_metrics(attr, current_path))
|
||||
series.extend(get_all_series(attr, current_path))
|
||||
|
||||
return metrics
|
||||
return series
|
||||
|
||||
|
||||
def test_all_endpoints():
|
||||
"""Test fetching last value from all metric endpoints."""
|
||||
"""Test fetching last value from all series endpoints."""
|
||||
client = BrkClient("http://localhost:3110")
|
||||
|
||||
metrics = get_all_metrics(client.metrics)
|
||||
print(f"\nFound {len(metrics)} metrics")
|
||||
series = get_all_series(client.series)
|
||||
print(f"\nFound {len(series)} series")
|
||||
|
||||
success = 0
|
||||
|
||||
for path, metric in metrics:
|
||||
for path, s in series:
|
||||
# Use the indexes() method to get all available indexes
|
||||
indexes = metric.indexes()
|
||||
indexes = s.indexes()
|
||||
|
||||
for idx_name in indexes:
|
||||
full_path = f"{path}.by.{idx_name}"
|
||||
|
||||
try:
|
||||
# Verify both access methods work: .by.index() and .get(index)
|
||||
by = metric.by
|
||||
by = s.by
|
||||
endpoint_by_property = getattr(by, idx_name)()
|
||||
endpoint_by_get = metric.get(idx_name)
|
||||
endpoint_by_get = s.get(idx_name)
|
||||
|
||||
if endpoint_by_property is None:
|
||||
raise Exception(f"metric.by.{idx_name}() returned None")
|
||||
raise Exception(f"series.by.{idx_name}() returned None")
|
||||
if endpoint_by_get is None:
|
||||
raise Exception(f"metric.get('{idx_name}') returned None")
|
||||
raise Exception(f"series.get('{idx_name}') returned None")
|
||||
|
||||
endpoint_by_property.tail(1).fetch()
|
||||
success += 1
|
||||
|
||||
Reference in New Issue
Block a user