"""KRX 호가단위(tick) 유틸 단위 테스트 (REQ-083, dcy-030).""" import pytest from trex_core.domain.pricing import ceil_to_tick, floor_to_tick, krx_stock_tick class TestKrxStockTick: @pytest.mark.parametrize("price,tick", [ (1_500, 1), (3_000, 5), (12_000, 10), (35_000, 50), (147_700, 100), (300_000, 500), (800_000, 1_000), ]) def test_representative_prices(self, price, tick): assert krx_stock_tick(price) == tick @pytest.mark.parametrize("boundary,tick", [ (2_000, 5), # [2000, 5000) -> 5 (lower bound inclusive) (5_000, 10), (20_000, 50), (50_000, 100), (200_000, 500), (500_000, 1_000), ]) def test_boundaries_are_lower_inclusive(self, boundary, tick): assert krx_stock_tick(boundary) == tick def test_just_below_boundary_uses_lower_band(self): assert krx_stock_tick(1_999) == 1 assert krx_stock_tick(49_999) == 50 assert krx_stock_tick(199_999) == 100 class TestFloorCeilToTick: def test_issue28_floor_cases(self): assert floor_to_tick(148_439) == 148_400 assert floor_to_tick(54_773) == 54_700 def test_ceil_case(self): assert ceil_to_tick(54_773) == 54_800 def test_already_on_tick_is_unchanged(self): assert floor_to_tick(147_700) == 147_700 assert ceil_to_tick(147_700) == 147_700 @pytest.mark.parametrize("price", [ 1_500, 2_777, 4_999, 12_345, 33_333, 148_439, 234_567, 777_777, ]) def test_invariants_floor_le_price_le_ceil_and_valid_multiples(self, price): tick = krx_stock_tick(price) f = floor_to_tick(price) c = ceil_to_tick(price) assert f <= price <= c assert f % krx_stock_tick(f) == 0 assert c % krx_stock_tick(c) == 0 assert c - f <= tick