feat(console): add formatting utils and VIN API client
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
168
console/tests/test_utils.py
Normal file
168
console/tests/test_utils.py
Normal file
@@ -0,0 +1,168 @@
|
||||
"""
|
||||
Tests for the formatting utility functions.
|
||||
|
||||
VIN API tests are excluded because they require network access.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from console.utils.formatting import (
|
||||
format_currency,
|
||||
format_number,
|
||||
truncate,
|
||||
pad_right,
|
||||
format_table_row,
|
||||
quality_bar,
|
||||
)
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# format_currency
|
||||
# =========================================================================
|
||||
|
||||
class TestFormatCurrency:
|
||||
def test_none_returns_dash(self):
|
||||
assert format_currency(None) == "──"
|
||||
|
||||
def test_zero_returns_zero_dollars(self):
|
||||
assert format_currency(0) == "$0.00"
|
||||
|
||||
def test_positive_value(self):
|
||||
assert format_currency(45.99) == "$45.99"
|
||||
|
||||
def test_integer_value(self):
|
||||
assert format_currency(100) == "$100.00"
|
||||
|
||||
def test_large_value_with_commas(self):
|
||||
assert format_currency(1234.56) == "$1,234.56"
|
||||
|
||||
def test_small_decimal(self):
|
||||
assert format_currency(0.5) == "$0.50"
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# format_number
|
||||
# =========================================================================
|
||||
|
||||
class TestFormatNumber:
|
||||
def test_none_returns_zero(self):
|
||||
assert format_number(None) == "0"
|
||||
|
||||
def test_zero(self):
|
||||
assert format_number(0) == "0"
|
||||
|
||||
def test_thousands_separator(self):
|
||||
assert format_number(13685) == "13,685"
|
||||
|
||||
def test_small_number(self):
|
||||
assert format_number(42) == "42"
|
||||
|
||||
def test_million(self):
|
||||
assert format_number(1000000) == "1,000,000"
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# truncate
|
||||
# =========================================================================
|
||||
|
||||
class TestTruncate:
|
||||
def test_none_returns_empty(self):
|
||||
assert truncate(None, 10) == ""
|
||||
|
||||
def test_short_string_unchanged(self):
|
||||
assert truncate("hello", 10) == "hello"
|
||||
|
||||
def test_exact_length_unchanged(self):
|
||||
assert truncate("hello", 5) == "hello"
|
||||
|
||||
def test_long_string_truncated_with_ellipsis(self):
|
||||
assert truncate("hello world!", 8) == "hello..."
|
||||
|
||||
def test_very_short_max_len(self):
|
||||
result = truncate("hello world", 3)
|
||||
assert result == "..."
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# pad_right
|
||||
# =========================================================================
|
||||
|
||||
class TestPadRight:
|
||||
def test_none_returns_empty(self):
|
||||
assert pad_right(None, 10) == ""
|
||||
|
||||
def test_short_string_padded(self):
|
||||
result = pad_right("hi", 5)
|
||||
assert result == "hi "
|
||||
assert len(result) == 5
|
||||
|
||||
def test_exact_length_unchanged(self):
|
||||
result = pad_right("hello", 5)
|
||||
assert result == "hello"
|
||||
|
||||
def test_long_string_truncated(self):
|
||||
result = pad_right("hello world", 5)
|
||||
assert result == "hello"
|
||||
assert len(result) == 5
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# format_table_row
|
||||
# =========================================================================
|
||||
|
||||
class TestFormatTableRow:
|
||||
def test_basic_row(self):
|
||||
result = format_table_row(["A", "B", "C"], [5, 5, 5])
|
||||
assert " │ " in result
|
||||
assert len(result.split(" │ ")) == 3
|
||||
|
||||
def test_values_padded_to_widths(self):
|
||||
result = format_table_row(["hi", "there"], [5, 7])
|
||||
parts = result.split(" │ ")
|
||||
assert len(parts[0]) == 5
|
||||
assert len(parts[1]) == 7
|
||||
|
||||
def test_custom_separator(self):
|
||||
result = format_table_row(["A", "B"], [3, 3], separator=" | ")
|
||||
assert " | " in result
|
||||
|
||||
def test_truncation_when_value_exceeds_width(self):
|
||||
result = format_table_row(["toolongvalue", "ok"], [5, 5])
|
||||
parts = result.split(" │ ")
|
||||
assert len(parts[0]) == 5
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# quality_bar
|
||||
# =========================================================================
|
||||
|
||||
class TestQualityBar:
|
||||
def test_oem(self):
|
||||
result = quality_bar("oem")
|
||||
assert "█" in result
|
||||
assert len(result) > 0
|
||||
|
||||
def test_premium(self):
|
||||
result = quality_bar("premium")
|
||||
assert "█" in result
|
||||
|
||||
def test_standard(self):
|
||||
result = quality_bar("standard")
|
||||
assert "█" in result
|
||||
assert "░" in result
|
||||
|
||||
def test_economy(self):
|
||||
result = quality_bar("economy")
|
||||
assert "█" in result
|
||||
assert "░" in result
|
||||
|
||||
def test_oem_longer_than_economy(self):
|
||||
oem = quality_bar("oem")
|
||||
economy = quality_bar("economy")
|
||||
oem_blocks = oem.count("█")
|
||||
economy_blocks = economy.count("█")
|
||||
assert oem_blocks > economy_blocks
|
||||
|
||||
def test_unknown_tier_returns_string(self):
|
||||
result = quality_bar("unknown")
|
||||
assert isinstance(result, str)
|
||||
Reference in New Issue
Block a user