"""Tests for ledgerly.money (R3, Money value semantics).""" import pytest from ledgerly.money import InvalidMoney, Money def test_parse_integer_string(): assert Money.parse("42") == Money(4200) def test_parse_two_decimals(): assert Money.parse("12.34") == Money(1234) def test_parse_rounds_half_up(): assert Money.parse("12.345") == Money(1235) assert Money.parse("12.344") == Money(1234) def test_parse_negative(): assert Money.parse("-1.50") == Money(-150) def test_parse_accepts_numbers(): assert Money.parse(3) == Money(300) assert Money.parse(2.5) == Money(250) def test_parse_rejects_garbage(): for bad in ("abc", "", None): with pytest.raises(InvalidMoney): Money.parse(bad) def test_parse_rejects_non_finite(): for bad in ("inf", "-inf", "nan"): with pytest.raises(InvalidMoney): Money.parse(bad) def test_cents_must_be_int(): for bad in ("5", 1.5, True): with pytest.raises(TypeError): Money(bad) def test_predicates(): assert Money(0).is_zero assert not Money(1).is_zero assert Money(1).is_positive assert not Money(0).is_positive assert not Money(-1).is_positive def test_zero_classmethod(): assert Money.zero() == Money(0) def test_arithmetic(): a, b = Money(100), Money(25) assert a + b == Money(125) assert a - b == Money(75) assert Money(10) - Money(20) == Money(-10) def test_arithmetic_type_errors(): with pytest.raises(TypeError): Money(1) + 1 with pytest.raises(TypeError): Money(1) - "1" def test_ordering_and_hash(): assert Money(1) < Money(2) assert Money(2) <= Money(2) assert Money(2) == Money(2) assert hash(Money(2)) == hash(Money(2)) def test_not_equal_to_other_types(): assert Money(1) != 1 assert Money(1) != "1" def test_str_formatting(): assert str(Money(0)) == "$0.00" assert str(Money(123456)) == "$1,234.56" assert str(Money(-100)) == "-$1.00" def test_format_supports_alignment(): assert format(Money(150000), "<12") == "$1,500.00 " assert format(Money(150000), "") == "$1,500.00" def test_repr(): assert repr(Money(42)) == "Money(42)"