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 Money.NA.as_boolean() assert not Money.of(usd, zero, today).as_boolean() assert Money.of(usd, half, today).as_boolean() assert Money.of(usd, -half, today).as_boolean() ## With semantic overload assert not bool(Money.NA) assert not Money.of(usd, zero, today) assert Money.of(usd, half, today) assert Money.of(usd, -half, today)
def test_is_equal() -> None: ## Vanilla: assert Money.NA.is_equal(NoMoney) assert Money.NA.is_equal(NoneMoney()) assert not Money.NA.is_equal(Money.of(usd, zero, today)) assert Money.of(usd, zero, today).is_equal(Money.of(usd, zero, today)) assert Money.of(usd, half, today).is_equal(Money.of(usd, half, today)) assert not Money.of(usd, zero, today).is_equal(Money.of(eur, zero, today)) assert not Money.of(usd, zero, today).is_equal(Money.of(usd, half, today)) assert not Money.of(usd, zero, today).is_equal( Money.of(usd, zero, yesterday)) ## With operator overload: assert Money.NA == NoneMoney() assert Money.NA != Money.of(usd, zero, today) assert Money.of(usd, zero, today) == Money.of(usd, zero, today) assert Money.of(usd, half, today) == Money.of(usd, half, today) assert Money.of(usd, zero, today) != Money.of(eur, zero, today) assert Money.of(usd, zero, today) != Money.of(usd, half, today) assert Money.of(usd, zero, today) != Money.of(usd, zero, yesterday)
def test_comparisons() -> None: ## First use `Money.NA`s: assert not (Money.NA < Money.NA) assert Money.NA <= Money.NA assert not (Money.NA > Money.NA) assert Money.NA >= Money.NA ## Try mixed: assert Money.NA < Money.of(usd, -one, today) assert Money.NA <= Money.of(usd, -one, today) assert not (Money.NA > Money.of(usd, -one, today)) assert not (Money.NA >= Money.of(usd, -one, today)) ## ... and: assert not (Money.of(usd, -one, today) < Money.NA) assert not (Money.of(usd, -one, today) <= Money.NA) assert Money.of(usd, -one, today) > Money.NA assert Money.of(usd, -one, today) >= Money.NA ## With defined values: assert not (Money.of(usd, zero, today) < Money.of(usd, zero, today)) assert Money.of(usd, zero, today) <= Money.of(usd, zero, today) assert not (Money.of(usd, zero, today) > Money.of(usd, zero, today)) assert Money.of(usd, zero, today) >= Money.of(usd, zero, today) ## ... and: assert Money.of(usd, zero, today) < Money.of(usd, one, today) assert Money.of(usd, zero, today) <= Money.of(usd, one, today) assert not (Money.of(usd, zero, today) > Money.of(usd, one, today)) assert not (Money.of(usd, zero, today) >= Money.of(usd, one, today)) ## ... and: assert not (Money.of(usd, one, today) < Money.of(usd, zero, today)) assert not (Money.of(usd, one, today) <= Money.of(usd, zero, today)) assert Money.of(usd, one, today) > Money.of(usd, zero, today) assert Money.of(usd, one, today) >= Money.of(usd, zero, today)
def test_floor_division() -> None: ## First use `Money.NA`s: assert Money.NA.floor_divide(1) == Money.NA ## Vanilla subtraction: assert Money.of(usd, one, today).floor_divide(1) == Money.of(usd, one, today) assert Money.of(usd, one, today).floor_divide(2) == Money.of(usd, zero, today) assert Money.of(usd, -one, today).floor_divide(1) == Money.of(usd, -one, today) assert Money.of(usd, -one, today).floor_divide(2) == Money.of(usd, zero, today) ## Various divisor types: assert Money.of(usd, one, today).floor_divide(2) == Money.of(usd, zero, today) assert Money.of(usd, one, today).floor_divide(2.0) == Money.of(usd, zero, today) assert Money.of(usd, one, today).floor_divide(two) == Money.of(usd, zero, today) ## Division by zero: assert Money.of(usd, one, today).floor_divide(0) == Money.NA assert Money.of(usd, one, today).floor_divide(zero) == Money.NA assert Money.of(usd, one, today).floor_divide(0.0) == Money.NA ## Operator overload: assert Money.NA / 1 == Money.NA assert Money.of(usd, one, today) // 1 == Money.of(usd, one, today) assert Money.of(usd, one, today) // 2 == Money.of(usd, zero, today) assert Money.of(usd, -one, today) // 1 == Money.of(usd, -one, today) assert Money.of(usd, -one, today) // 2 == Money.of(usd, zero, today) assert Money.of(usd, -one, today) // 0 == Money.NA ## Extras assert Money.of(usd, Decimal("10"), today).floor_divide(Decimal("10")) == Money.of( usd, Decimal("1.00"), today) assert Money.of(usd, Decimal("10"), today).floor_divide(Decimal("11")) == Money.of( usd, Decimal("0.00"), today)
def test_scalar_multiplication() -> None: ## First use `Money.NA`s: assert Money.NA.multiply(1) == Money.NA ## Vanilla subtraction: assert Money.of(usd, one, today).multiply(1) == Money.of(usd, one, today) assert Money.of(usd, one, today).multiply(2) == Money.of(usd, two, today) assert Money.of(usd, -one, today).multiply(1) == Money.of(usd, -one, today) assert Money.of(usd, -one, today).multiply(2) == Money.of(usd, -two, today) ## Other types: assert Money.of(usd, one, today).multiply(1) == Money.of(usd, one, today) assert Money.of(usd, one, today).multiply(1.0) == Money.of(usd, one, today) assert Money.of(usd, one, today).multiply(one) == Money.of(usd, one, today) ## Operator overload: assert Money.NA * 1 == Money.NA assert Money.of(usd, one, today) * 1 == Money.of(usd, one, today) assert Money.of(usd, one, today) * 2 == Money.of(usd, two, today) assert Money.of(usd, -one, today) * 1 == Money.of(usd, -one, today) assert Money.of(usd, -one, today) * 2 == Money.of(usd, -two, today) ## Extras assert Money.of(usd, one, today).multiply(Decimal("0.050")) == Money.of( usd, Decimal("0.05"), today) assert Money.of(usd, one, today).multiply(Decimal("0.005")) == Money.of( usd, Decimal("0.00"), today) assert Money.of(usd, one, today).multiply(Decimal("0.015")) == Money.of( usd, Decimal("0.02"), today)
def test_scalar_subtraction() -> None: ## First use `Money.NA`s: assert Money.NA.scalar_subtract(1) == Money.NA ## Vanilla subtraction: assert Money.of(usd, zero, today).scalar_subtract(1) == Money.of(usd, -one, today) assert Money.of(usd, zero, today).scalar_subtract(1.0) == Money.of(usd, -one, today) assert Money.of(usd, zero, today).scalar_subtract(one) == Money.of(usd, -one, today) assert Money.of(usd, zero, today).scalar_subtract(-1) == Money.of(usd, one, today) ## Operator overload: assert Money.of(usd, zero, today).scalar_subtract(1) == Money.of(usd, -one, today) assert Money.of(usd, zero, today).scalar_subtract(-1) == Money.of(usd, one, today) ## Extras: assert Money.of(usd, zero, today).scalar_subtract(0.5) == Money.of(usd, -half, today) assert Money.of(usd, zero, today).scalar_subtract( Decimal("0.05")) == -Money.of(usd, Decimal("0.05"), today) assert Money.of(usd, zero, today).scalar_subtract( Decimal("0.005")) == -Money.of(usd, Decimal("0"), today) assert Money.of(usd, zero, today).scalar_subtract( Decimal("0.015")) == -Money.of(usd, Decimal("0.02"), today)
def test_subtraction() -> None: ## First use `Money.NA`s: assert Money.NA.subtract(Money.NA) == Money.NA assert Money.NA.subtract(Money.of(usd, zero, today)) == Money.of(usd, zero, today) assert Money.of(usd, zero, today).subtract(Money.NA) == Money.of(usd, zero, today) ## Vanilla subtraction: assert Money.of(usd, zero, today).subtract(Money.of(usd, zero, today)) == Money.of( usd, zero, today) assert Money.of(usd, zero, today).subtract(Money.of(usd, one, today)) == Money.of( usd, -one, today) assert Money.of(usd, one, today).subtract(Money.of(usd, one, today)) == Money.of( usd, zero, today) assert Money.of(usd, one, today).subtract(Money.of(usd, -one, today)) == Money.of( usd, two, today) ## Carry dates forward: assert Money.of(usd, zero, today).subtract(Money.of(usd, one, yesterday)) == Money.of( usd, -one, today) assert Money.of(usd, zero, yesterday).subtract(Money.of(usd, one, today)) == Money.of( usd, -one, today) ## Incompatible currency errors: with pytest.raises(IncompatibleCurrencyError): Money.of(usd, zero, today).subtract(Money.of(eur, zero, today)) ## Operator overload: assert Money.of(usd, zero, today) - Money.of(usd, one, today) == Money.of( usd, -one, today) assert Money.NA - Money.NA == Money.NA assert Money.NA - Money.of(usd, zero, today) == Money.of(usd, zero, today) assert Money.of(usd, zero, today) - Money.NA == Money.of(usd, zero, today)
def test_scalar_addition() -> None: ## First use `Money.NA`s: assert Money.NA.scalar_add(1) == Money.NA ## Vanilla addition: assert Money.of(usd, zero, today).scalar_add(1) == Money.of(usd, one, today) assert Money.of(usd, zero, today).scalar_add(1.0) == Money.of(usd, one, today) assert Money.of(usd, zero, today).scalar_add(one) == Money.of(usd, one, today) assert Money.of(usd, zero, today).scalar_add(-1) == Money.of(usd, -one, today) ## Extras: assert Money.of(usd, zero, today).scalar_add(0.5) == Money.of(usd, half, today) assert Money.of(usd, zero, today).scalar_add(Decimal("0.05")) == Money.of( usd, Decimal("0.05"), today) assert Money.of(usd, zero, today).scalar_add(Decimal("0.005")) == Money.of( usd, Decimal("0"), today) assert Money.of(usd, zero, today).scalar_add(Decimal("0.015")) == Money.of( usd, Decimal("0.02"), today)
def test_round() -> None: ## Vanilla: assert Money.NA.round(2) == Money.NA assert Money.of(usd, zero, today).round(2) == Money.of(usd, zero, today) assert Money.of(usd, -one, today).round(2) == Money.of(usd, -one, today) assert Money.of(usd, +one, today).round(2) == Money.of(usd, +one, today) ## Quick tests: assert Money.of(usd, Decimal("1.555"), today).round(2) == Money.of(usd, Decimal("1.56"), today) assert Money.of(usd, Decimal("1.545"), today).round(2) == Money.of(usd, Decimal("1.54"), today) ## With overload: assert round(Money.NA, 2) == Money.NA assert round(Money.of(usd, zero, today), 2) == Money.of(usd, zero, today) assert round(Money.of(usd, -one, today), 2) == Money.of(usd, -one, today) assert round(Money.of(usd, +one, today), 2) == Money.of(usd, +one, today) assert round(Money.of(usd, Decimal("1.555"), today), 2) == Money.of(usd, Decimal("1.56"), today) assert round(Money.of(usd, Decimal("1.545"), today), 2) == Money.of(usd, Decimal("1.54"), today) ## Extras: assert round(Money.of(usd, Decimal("0.545"), today), 0) == Money.of(usd, Decimal("1"), today) assert round(Money.of(usd, Decimal("1.545"), today), 0) == Money.of(usd, Decimal("2"), today) assert round(Money.of(usd, Decimal("0.545"), today), 1) == Money.of(usd, Decimal("0.5"), today) assert round(Money.of(usd, Decimal("1.545"), today), 1) == Money.of(usd, Decimal("1.5"), today) assert round(Money.of(usd, Decimal("0.45"), today), 1) == Money.of(usd, Decimal("0.4"), today) assert round(Money.of(usd, Decimal("1.45"), today), 1) == Money.of(usd, Decimal("1.4"), today) ## TODO: Following two are not really what round function signature says. mypy can't detect it! assert round(Money.of(usd, Decimal("1.4"), today)) == Money.of(usd, Decimal("1"), today) assert round(Money.of(usd, Decimal("1.5"), today)) == Money.of(usd, Decimal("2"), today)
def test_positive() -> None: ## Vanilla: assert Money.NA.positive() == Money.NA assert Money.of(usd, zero, today).positive() == Money.of(usd, zero, today) assert Money.of(usd, -one, today).positive() == Money.of(usd, -one, today) assert Money.of(usd, +one, today).positive() == Money.of(usd, +one, today) ## With overload: assert +Money.NA == Money.NA assert +Money.of(usd, zero, today) == Money.of(usd, zero, today) assert +Money.of(usd, -one, today) == Money.of(usd, -one, today) assert +Money.of(usd, +one, today) == Money.of(usd, +one, today)
def test_negative() -> None: ## Vanilla: assert Money.NA.negative() == Money.NA assert Money.of(usd, zero, today).negative() == Money.of(usd, zero, today) assert Money.of(usd, -one, today).negative() == Money.of(usd, +one, today) assert Money.of(usd, +one, today).negative() == Money.of(usd, -one, today) ## With overload: assert -Money.NA == Money.NA assert -Money.of(usd, zero, today) == Money.of(usd, zero, today) assert -Money.of(usd, -one, today) == Money.of(usd, +one, today) assert -Money.of(usd, +one, today) == Money.of(usd, -one, today)
def test_abs() -> None: ## Vanilla: assert Money.NA.abs() == Money.NA assert Money.of(usd, zero, today).abs() == Money.of(usd, zero, today) assert Money.of(usd, -one, today).abs() == Money.of(usd, +one, today) assert Money.of(usd, +one, today).abs() == Money.of(usd, +one, today) ## With overload: assert abs(Money.NA) == Money.NA assert abs(Money.of(usd, zero, today)) == Money.of(usd, zero, today) assert abs(Money.of(usd, -one, today)) == Money.of(usd, +one, today) assert abs(Money.of(usd, +one, today)) == Money.of(usd, +one, today)