def test_to_float() -> None: ## Vanilla: with pytest.raises(TypeError): Price.NA.as_float() assert Price.of(usd, half, today).as_float() == 0.5 assert type(Price.of(usd, half, today).as_float()) == float ## With overload: with pytest.raises(TypeError): float(Price.NA) assert float(Price.of(usd, half, today)) == 0.5 assert type(float(Price.of(usd, half, today))) == float
def test_to_integer() -> None: ## Vanilla: with pytest.raises(TypeError): int(Price.NA) assert int(Price.of(usd, half, today)) == 0 assert type(int(Price.of(usd, half, today))) == int ## With overload: with pytest.raises(TypeError): Price.NA.as_integer() assert Price.of(usd, half, today).as_integer() == 0 assert type(Price.of(usd, half, today).as_integer()) == int
def test_implementation() -> None: ## Define instances: _price = Price() # type: ignore sprice = SomePrice(usd, one, today) nprice = NonePrice() ## Check structure: assert _price.__slots__ == () assert sprice.__slots__ == () assert nprice.__slots__ == () assert not hasattr(_price, "__dict__") assert not hasattr(sprice, "__dict__") assert not hasattr(nprice, "__dict__") ## Check types assert isinstance(Price.NA, Price) assert isinstance(Price.NA, NonePrice) assert not isinstance(Price.NA, SomePrice) assert not isinstance(Price.NA, Money) assert isinstance(_price, Price) assert not isinstance(_price, SomePrice) assert not isinstance(_price, NonePrice) assert isinstance(sprice, Price) assert isinstance(sprice, SomePrice) assert not isinstance(sprice, NonePrice) assert isinstance(nprice, Price) assert not isinstance(nprice, SomePrice) assert isinstance(nprice, NonePrice)
def test_scalar_addition() -> None: ## First use `Price.NA`s: assert Price.NA.scalar_add(1) == Price.NA ## Vanilla addition: assert Price.of(usd, zero, today).scalar_add(1) == Price.of(usd, one, today) assert Price.of(usd, zero, today).scalar_add(1.0) == Price.of(usd, one, today) assert Price.of(usd, zero, today).scalar_add(one) == Price.of(usd, one, today) assert Price.of(usd, zero, today).scalar_add(-1) == Price.of(usd, -one, today)
def test_monetary_multiplication() -> None: ## First use `Price.NA`s: assert Price.NA.times(1) == Money.NA ## Vanilla multiplication: assert Price.of(usd, one, today).times(1) == Money.of(usd, one, today) assert Price.of(usd, one, today).times(2) == Money.of(usd, two, today) assert Price.of(usd, -one, today).times(1) == Money.of(usd, -one, today) assert Price.of(usd, -one, today).times(2) == Money.of(usd, -two, today) ## Other types: assert Price.of(usd, one, today).times(1) == Money.of(usd, one, today) assert Price.of(usd, one, today).times(1.0) == Money.of(usd, one, today) assert Price.of(usd, one, today).times(one) == Money.of(usd, one, today)
def test_to_boolean() -> None: ## Vanilla: assert not Price.NA.as_boolean() assert not Price.of(usd, zero, today).as_boolean() assert Price.of(usd, half, today).as_boolean() assert Price.of(usd, -half, today).as_boolean() ## With semantic overload assert not bool(Price.NA) assert not Price.of(usd, zero, today) assert Price.of(usd, half, today) assert Price.of(usd, -half, today)
def test_with() -> None: ## First use `Price.NA`s: assert Price.NA.with_ccy(usd) == Price.NA assert Price.NA.with_qty(one) == Price.NA assert Price.NA.with_dov(today) == Price.NA ## Now with some: assert Price.of(usd, zero, today).with_ccy(eur) == Price.of(eur, zero, today) assert Price.of(usd, zero, today).with_qty(one) == Price.of(usd, one, today) assert Price.of(usd, zero, today).with_dov(yesterday) == Price.of( usd, zero, yesterday)
def test_scalar_multiplication() -> None: ## First use `Price.NA`s: assert Price.NA.multiply(1) == Price.NA ## Vanilla subtraction: assert Price.of(usd, one, today).multiply(1) == Price.of(usd, one, today) assert Price.of(usd, one, today).multiply(2) == Price.of(usd, two, today) assert Price.of(usd, -one, today).multiply(1) == Price.of(usd, -one, today) assert Price.of(usd, -one, today).multiply(2) == Price.of(usd, -two, today) ## Other types: assert Price.of(usd, one, today).multiply(1) == Price.of(usd, one, today) assert Price.of(usd, one, today).multiply(1.0) == Price.of(usd, one, today) assert Price.of(usd, one, today).multiply(one) == Price.of(usd, one, today) ## Operator overload: assert Price.NA * 1 == Price.NA assert Price.of(usd, one, today) * 1 == Price.of(usd, one, today) assert Price.of(usd, one, today) * 2 == Price.of(usd, two, today) assert Price.of(usd, -one, today) * 1 == Price.of(usd, -one, today) assert Price.of(usd, -one, today) * 2 == Price.of(usd, -two, today)
def test_is_equal() -> None: ## Vanilla: assert Price.NA.is_equal(NoPrice) assert Price.NA.is_equal(NonePrice()) assert not Price.NA.is_equal(Price.of(usd, zero, today)) assert Price.of(usd, zero, today).is_equal(Price.of(usd, zero, today)) assert Price.of(usd, half, today).is_equal(Price.of(usd, half, today)) assert not Price.of(usd, zero, today).is_equal(Price.of(eur, zero, today)) assert not Price.of(usd, zero, today).is_equal(Price.of(usd, half, today)) assert not Price.of(usd, zero, today).is_equal( Price.of(usd, zero, yesterday)) ## With operator overload: assert Price.NA == NonePrice() assert Price.NA != Price.of(usd, zero, today) assert Price.of(usd, zero, today) == Price.of(usd, zero, today) assert Price.of(usd, half, today) == Price.of(usd, half, today) assert Price.of(usd, zero, today) != Price.of(eur, zero, today) assert Price.of(usd, zero, today) != Price.of(usd, half, today) assert Price.of(usd, zero, today) != Price.of(usd, zero, yesterday)
def test_of() -> None: assert Price.of(usd, one, None) == Price.NA assert Price.of(usd, None, today) == Price.NA assert Price.of(usd, one, None) == Price.NA assert Price.of(usd, one, today) == SomePrice(usd, one, today)
def test_comparisons() -> None: ## First use `Price.NA`s: assert not (Price.NA < Price.NA) assert Price.NA <= Price.NA assert not (Price.NA > Price.NA) assert Price.NA >= Price.NA ## Try mixed: assert Price.NA < Price.of(usd, -one, today) assert Price.NA <= Price.of(usd, -one, today) assert not (Price.NA > Price.of(usd, -one, today)) assert not (Price.NA >= Price.of(usd, -one, today)) ## ... and: assert not (Price.of(usd, -one, today) < Price.NA) assert not (Price.of(usd, -one, today) <= Price.NA) assert Price.of(usd, -one, today) > Price.NA assert Price.of(usd, -one, today) >= Price.NA ## With defined values: assert not (Price.of(usd, zero, today) < Price.of(usd, zero, today)) assert Price.of(usd, zero, today) <= Price.of(usd, zero, today) assert not (Price.of(usd, zero, today) > Price.of(usd, zero, today)) assert Price.of(usd, zero, today) >= Price.of(usd, zero, today) ## ... and: assert Price.of(usd, zero, today) < Price.of(usd, one, today) assert Price.of(usd, zero, today) <= Price.of(usd, one, today) assert not (Price.of(usd, zero, today) > Price.of(usd, one, today)) assert not (Price.of(usd, zero, today) >= Price.of(usd, one, today)) ## ... and: assert not (Price.of(usd, one, today) < Price.of(usd, zero, today)) assert not (Price.of(usd, one, today) <= Price.of(usd, zero, today)) assert Price.of(usd, one, today) > Price.of(usd, zero, today) assert Price.of(usd, one, today) >= Price.of(usd, zero, today)
def test_floor_division() -> None: ## First use `Price.NA`s: assert Price.NA.floor_divide(1) == Price.NA ## Vanilla subtraction: assert Price.of(usd, one, today).floor_divide(1) == Price.of(usd, one, today) assert Price.of(usd, one, today).floor_divide(2) == Price.of(usd, zero, today) assert Price.of(usd, -one, today).floor_divide(1) == Price.of(usd, -one, today) assert Price.of(usd, -one, today).floor_divide(2) == Price.of(usd, zero, today) ## Various divisor types: assert Price.of(usd, one, today).floor_divide(2) == Price.of(usd, zero, today) assert Price.of(usd, one, today).floor_divide(2.0) == Price.of(usd, zero, today) assert Price.of(usd, one, today).floor_divide(two) == Price.of(usd, zero, today) ## Division by zero: assert Price.of(usd, one, today).floor_divide(0) == Price.NA assert Price.of(usd, one, today).floor_divide(zero) == Price.NA assert Price.of(usd, one, today).floor_divide(0.0) == Price.NA ## Operator overload: assert Price.NA / 1 == Price.NA assert Price.of(usd, one, today) // 1 == Price.of(usd, one, today) assert Price.of(usd, one, today) // 2 == Price.of(usd, zero, today) assert Price.of(usd, -one, today) // 1 == Price.of(usd, -one, today) assert Price.of(usd, -one, today) // 2 == Price.of(usd, zero, today) assert Price.of(usd, -one, today) // 0 == Price.NA
def test_abs() -> None: ## Vanilla: assert Price.NA.abs() == Price.NA assert Price.of(usd, zero, today).abs() == Price.of(usd, zero, today) assert Price.of(usd, -one, today).abs() == Price.of(usd, +one, today) assert Price.of(usd, +one, today).abs() == Price.of(usd, +one, today) ## With overload: assert abs(Price.NA) == Price.NA assert abs(Price.of(usd, zero, today)) == Price.of(usd, zero, today) assert abs(Price.of(usd, -one, today)) == Price.of(usd, +one, today) assert abs(Price.of(usd, +one, today)) == Price.of(usd, +one, today)
def test_scalar_subtraction() -> None: ## First use `Price.NA`s: assert Price.NA.scalar_subtract(1) == Price.NA ## Vanilla subtraction: assert Price.of(usd, zero, today).scalar_subtract(1) == Price.of(usd, -one, today) assert Price.of(usd, zero, today).scalar_subtract(1.0) == Price.of(usd, -one, today) assert Price.of(usd, zero, today).scalar_subtract(one) == Price.of(usd, -one, today) assert Price.of(usd, zero, today).scalar_subtract(-1) == Price.of(usd, one, today) ## Operator overload: assert Price.of(usd, zero, today).scalar_subtract(1) == Price.of(usd, -one, today) assert Price.of(usd, zero, today).scalar_subtract(-1) == Price.of(usd, one, today)
def test_subtraction() -> None: ## First use `Price.NA`s: assert Price.NA.subtract(Price.NA) == Price.NA assert Price.NA.subtract(Price.of(usd, zero, today)) == Price.of(usd, zero, today) assert Price.of(usd, zero, today).subtract(Price.NA) == Price.of(usd, zero, today) ## Vanilla subtraction: assert Price.of(usd, zero, today).subtract(Price.of(usd, zero, today)) == Price.of( usd, zero, today) assert Price.of(usd, zero, today).subtract(Price.of(usd, one, today)) == Price.of( usd, -one, today) assert Price.of(usd, one, today).subtract(Price.of(usd, one, today)) == Price.of( usd, zero, today) assert Price.of(usd, one, today).subtract(Price.of(usd, -one, today)) == Price.of( usd, two, today) ## Carry dates forward: assert Price.of(usd, zero, today).subtract(Price.of(usd, one, yesterday)) == Price.of( usd, -one, today) assert Price.of(usd, zero, yesterday).subtract(Price.of(usd, one, today)) == Price.of( usd, -one, today) ## Incompatible currency errors: with pytest.raises(IncompatibleCurrencyError): Price.of(usd, zero, today).subtract(Price.of(eur, zero, today)) ## Operator overload: assert Price.of(usd, zero, today) - Price.of(usd, one, today) == Price.of( usd, -one, today) assert Price.NA - Price.NA == Price.NA assert Price.NA - Price.of(usd, zero, today) == Price.of(usd, zero, today) assert Price.of(usd, zero, today) - Price.NA == Price.of(usd, zero, today)
def test_round() -> None: ## Vanilla: assert Price.NA.round(2) == Price.NA assert Price.of(usd, zero, today).round(2) == Price.of(usd, zero, today) assert Price.of(usd, -one, today).round(2) == Price.of(usd, -one, today) assert Price.of(usd, +one, today).round(2) == Price.of(usd, +one, today) ## Quick tests: assert Price.of(usd, Decimal("1.555"), today).round(2) == Price.of(usd, Decimal("1.56"), today) assert Price.of(usd, Decimal("1.545"), today).round(2) == Price.of(usd, Decimal("1.54"), today) ## With overload: assert round(Price.NA, 2) == Price.NA assert round(Price.of(usd, zero, today), 2) == Price.of(usd, zero, today) assert round(Price.of(usd, -one, today), 2) == Price.of(usd, -one, today) assert round(Price.of(usd, +one, today), 2) == Price.of(usd, +one, today) assert round(Price.of(usd, Decimal("1.555"), today), 2) == Price.of(usd, Decimal("1.56"), today) assert round(Price.of(usd, Decimal("1.545"), today), 2) == Price.of(usd, Decimal("1.54"), today) ## TODO: Following two are not really what round function signature says. mypy can't detect it! assert round(Price.of(usd, Decimal("1.4"), today)) == Price.of(usd, Decimal("1"), today) assert round(Price.of(usd, Decimal("1.5"), today)) == Price.of(usd, Decimal("2"), today)
def test_positive() -> None: ## Vanilla: assert Price.NA.positive() == Price.NA assert Price.of(usd, zero, today).positive() == Price.of(usd, zero, today) assert Price.of(usd, -one, today).positive() == Price.of(usd, -one, today) assert Price.of(usd, +one, today).positive() == Price.of(usd, +one, today) ## With overload: assert +Price.NA == Price.NA assert +Price.of(usd, zero, today) == Price.of(usd, zero, today) assert +Price.of(usd, -one, today) == Price.of(usd, -one, today) assert +Price.of(usd, +one, today) == Price.of(usd, +one, today)