From d77d5523bfcd6c13be1aa933f7ee9a9fe305aafa Mon Sep 17 00:00:00 2001 From: Helmut Hummel Date: Thu, 14 Apr 2022 13:01:55 +0200 Subject: [PATCH] Allow divisor in mod to be a number as well Fixes #687 --- src/Money.php | 18 +++++++++++++----- tests/MoneyTest.php | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/Money.php b/src/Money.php index a43d5ba0..e53a3d9e 100644 --- a/src/Money.php +++ b/src/Money.php @@ -272,14 +272,22 @@ public function divide(int|string $divisor, int $roundingMode = self::ROUND_HALF * the remainder after dividing the value by * the given factor. */ - public function mod(Money $divisor): Money + public function mod(Money|int|string $divisor): Money { - // Note: non-strict equality is intentional here, since `Currency` is `final` and reliable. - if ($this->currency != $divisor->currency) { - throw new InvalidArgumentException('Currencies must be identical'); + if ($divisor instanceof self) { + // Note: non-strict equality is intentional here, since `Currency` is `final` and reliable. + if ($this->currency != $divisor->currency) { + throw new InvalidArgumentException('Currencies must be identical'); + } + $amount = $divisor->amount; + } else { + if (is_int($divisor)) { + $divisor = (string) $divisor; + } + $amount = $divisor; } - return new self(self::$calculator::mod($this->amount, $divisor->amount), $this->currency); + return new self(self::$calculator::mod($this->amount, $amount), $this->currency); } /** diff --git a/tests/MoneyTest.php b/tests/MoneyTest.php index 5c20ab94..971035d0 100644 --- a/tests/MoneyTest.php +++ b/tests/MoneyTest.php @@ -257,6 +257,24 @@ public function itCalculatesTheModulusOfAnAmount($left, $right, $expected): void self::assertEquals($expected, $money->getAmount()); } + /** + * @psalm-param positive-int $left + * @psalm-param positive-int $right + * @psalm-param numeric-string $expected + * + * @dataProvider modExamples + * @test + */ + public function itCalculatesTheModulusOfNumber($left, $right, $expected): void + { + $money = new Money($left, new Currency(self::CURRENCY)); + + $money = $money->mod($right); + + self::assertInstanceOf(Money::class, $money); + self::assertEquals($expected, $money->getAmount()); + } + /** * @test */