diff --git a/tests/Currencies/CachedCurrenciesTest.php b/tests/Currencies/CachedCurrenciesTest.php index 38ce1de7..0993e817 100644 --- a/tests/Currencies/CachedCurrenciesTest.php +++ b/tests/Currencies/CachedCurrenciesTest.php @@ -122,4 +122,71 @@ public function it_is_iterable(): void iterator_to_array(new CachedCurrencies($wrappedCurrencies, $cache)) ); } + + /** @test */ + public function it_checks_subunits_from_the_cache(): void + { + $currency = new Currency('EUR'); + + $hit = $this->createMock(CacheItemInterface::class); + $cache = $this->createMock(CacheItemPoolInterface::class); + $wrappedCurrencies = $this->createMock(Currencies::class); + + $hit->method('isHit') + ->willReturn(true); + $hit->expects(self::never()) + ->method('set'); + $hit->method('get') + ->willReturn(2); + + $cache->method('getItem') + ->with('currency|subunit|EUR') + ->willReturn($hit); + $cache->expects(self::never()) + ->method('save'); + + $wrappedCurrencies->expects(self::never()) + ->method('subunitFor'); + + self::assertEquals( + 2, + (new CachedCurrencies($wrappedCurrencies, $cache)) + ->subunitFor($currency) + ); + } + + /** @test */ + public function it_saves_subunits_to_the_cache(): void + { + $currency = new Currency('EUR'); + + $hit = $this->createMock(CacheItemInterface::class); + $cache = $this->createMock(CacheItemPoolInterface::class); + $wrappedCurrencies = $this->createMock(Currencies::class); + + $hit->method('isHit') + ->willReturn(false); + $hit->expects(self::once()) + ->method('set') + ->with(2); + $hit->expects(self::once()) + ->method('get') + ->willReturn(2); + + $cache->method('getItem') + ->with('currency|subunit|EUR') + ->willReturn($hit); + $cache->expects(self::once()) + ->method('save'); + + $wrappedCurrencies->expects(self::once()) + ->method('subunitFor') + ->willReturn(2); + + self::assertEquals( + 2, + (new CachedCurrencies($wrappedCurrencies, $cache)) + ->subunitFor($currency) + ); + } } diff --git a/tests/CurrencyPairTest.php b/tests/CurrencyPairTest.php index bba68ce9..7ccdfebe 100644 --- a/tests/CurrencyPairTest.php +++ b/tests/CurrencyPairTest.php @@ -16,54 +16,64 @@ final class CurrencyPairTest extends TestCase /** * @test */ - public function itConvertsToJson(): void - { - $expectedJson = '{"baseCurrency":"EUR","counterCurrency":"USD","ratio":"1.25"}'; - $actualJson = json_encode(new CurrencyPair(new Currency('EUR'), new Currency('USD'), '1.25')); - - self::assertEquals($expectedJson, $actualJson); - } - - /** @test */ - public function it_parses_an_iso_string(): void + public function itProvidesGetters(): void { - self::assertEquals( - new CurrencyPair(new Currency('EUR'), new Currency('USD'), '1.250000'), - CurrencyPair::createFromIso('EUR/USD 1.250000') + $pair = new CurrencyPair( + new Currency('USD'), + new Currency('EUR'), + '1.0' ); + + self::assertEquals('USD', $pair->getBaseCurrency()->getCode()); + self::assertEquals('EUR', $pair->getCounterCurrency()->getCode()); + self::assertEquals('1.0', $pair->getConversionRatio()); } - /** @test */ - public function it_equals_to_another_currency_pair(): void + /** + * @test + */ + public function itProvidesEquality(): void { - $pair = new CurrencyPair( - new Currency('EUR'), + $pair1 = new CurrencyPair( new Currency('USD'), - '1.250000' + new Currency('EUR'), + '1.0' ); - self::assertFalse($pair->equals(new CurrencyPair( - new Currency('GBP'), + self::assertTrue($pair1->equals(new CurrencyPair( new Currency('USD'), - '1.250000' - ))); - - self::assertFalse($pair->equals(new CurrencyPair( new Currency('EUR'), - new Currency('GBP'), - '1.250000' + '1.0' ))); - - self::assertFalse($pair->equals(new CurrencyPair( - new Currency('EUR'), + self::assertFalse($pair1->equals(new CurrencyPair( new Currency('USD'), - '1.5000' + new Currency('EUR'), + '2.0' ))); + } - self::assertTrue($pair->equals(new CurrencyPair( - new Currency('EUR'), + /** + * @test + */ + public function itConvertsToJson(): void + { + $pair = new CurrencyPair( new Currency('USD'), - '1.250000' - ))); + new Currency('EUR'), + '1.0' + ); + + self::assertEquals('{"baseCurrency":"USD","counterCurrency":"EUR","ratio":"1.0"}', json_encode($pair)); + } + + /** + * @test + */ + public function itCanBeCreatedWithAnIsoString(): void + { + $pair = CurrencyPair::createFromIso('EUR/USD 1.2500'); + self::assertEquals('EUR', $pair->getBaseCurrency()->getCode()); + self::assertEquals('USD', $pair->getCounterCurrency()->getCode()); + self::assertEquals('1.2500', $pair->getConversionRatio()); } } diff --git a/tests/CurrencyTest.php b/tests/CurrencyTest.php index 8a07a018..2500991a 100644 --- a/tests/CurrencyTest.php +++ b/tests/CurrencyTest.php @@ -27,4 +27,21 @@ public function itAppliesUppercase(): void { self::assertEquals('USD', (new Currency('usd'))->getCode()); } + + /** + * @test + */ + public function itIsStringable(): void + { + self::assertEquals('USD', (string) new Currency('usd')); + } + + /** + * @test + */ + public function itProvidesEqualityComparison(): void + { + $currency = new Currency('usd'); + self::assertTrue($currency->equals(new Currency('USD'))); + } } diff --git a/tests/Exchange/FixedExchangeTest.php b/tests/Exchange/FixedExchangeTest.php new file mode 100644 index 00000000..b26891a6 --- /dev/null +++ b/tests/Exchange/FixedExchangeTest.php @@ -0,0 +1,33 @@ + ['USD' => '1.2500']]); + $currencyPair = $exchange->quote(new Currency('EUR'), new Currency('USD')); + + self::assertEquals('EUR', $currencyPair->getBaseCurrency()); + self::assertEquals('USD', $currencyPair->getCounterCurrency()); + self::assertEquals('1.2500', $currencyPair->getConversionRatio()); + } + + /** @test */ + public function it_throws_when_quoting_unknown_currency(): void + { + $this->expectException(UnresolvableCurrencyPairException::class); + $exchange = new FixedExchange(['EUR' => ['USD' => '1.2500']]); + $exchange->quote(new Currency('EUR'), new Currency('SOME')); + } +} diff --git a/tests/MoneyTest.php b/tests/MoneyTest.php index 1aa23d35..5c20ab94 100644 --- a/tests/MoneyTest.php +++ b/tests/MoneyTest.php @@ -400,6 +400,26 @@ public function itRoundsToUnit($amount, $unit, $expected, $roundingMode): void self::assertEquals(Money::EUR($expected), Money::EUR($amount)->roundToUnit($unit, $roundingMode)); } + /** @test */ + public function itThrowsWithDecimal(): void + { + $this->expectException(InvalidArgumentException::class); + new Money('5.1', new Currency(self::CURRENCY)); + } + + /** + * @test + */ + public function itThrowsWhenComparingDifferentCurrencies(): void + { + $money = new Money('5', new Currency(self::CURRENCY)); + + $this->expectException(InvalidArgumentException::class); + + /** @psalm-suppress UnusedMethodCall */ + $money->compare(new Money('5', new Currency('SOME'))); + } + /** * @psalm-return non-empty-list