mirror of
https://github.com/archtechx/money.git
synced 2025-12-12 19:34:02 +00:00
Initial commit
This commit is contained in:
commit
8847454577
33 changed files with 2435 additions and 0 deletions
192
tests/Pest/CurrencyManagerTest.php
Normal file
192
tests/Pest/CurrencyManagerTest.php
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
|
||||
use ArchTech\Money\Currencies\USD;
|
||||
use ArchTech\Money\Currency;
|
||||
use ArchTech\Money\Tests\Currencies\CZK;
|
||||
use ArchTech\Money\Tests\Currencies\EUR;
|
||||
|
||||
beforeEach(fn () => currencies()->reset());
|
||||
|
||||
test('only USD is loaded by default', function () {
|
||||
expect(currencies()->all())
|
||||
->toHaveCount(1)
|
||||
->toHaveKey('USD');
|
||||
});
|
||||
|
||||
test('USD is the default currency', function () {
|
||||
expect(currencies()->getDefault())->toBeInstanceOf(USD::class);
|
||||
});
|
||||
|
||||
test('USD is the current currency', function () {
|
||||
expect(currencies()->getCurrent())->toBeInstanceOf(USD::class);
|
||||
});
|
||||
|
||||
test('the default currency can be changed', function () {
|
||||
currencies()->add([CZK::class, EUR::class]);
|
||||
|
||||
expect(currencies()->getDefault())->toBeInstanceOf(USD::class);
|
||||
|
||||
// Using class
|
||||
currencies()->setDefault(CZK::class);
|
||||
expect(currencies()->getDefault())->toBeInstanceOf(CZK::class);
|
||||
|
||||
// Using code
|
||||
currencies()->setDefault('EUR');
|
||||
expect(currencies()->getDefault())->toBeInstanceOf(EUR::class);
|
||||
});
|
||||
|
||||
test('the current currency can be changed', function () {
|
||||
currencies()->add([CZK::class, EUR::class]);
|
||||
|
||||
expect(currencies()->getCurrent())->toBeInstanceOf(USD::class);
|
||||
|
||||
// Using class
|
||||
currencies()->setCurrent(CZK::class);
|
||||
expect(currencies()->getCurrent())->toBeInstanceOf(CZK::class);
|
||||
|
||||
// Using code
|
||||
currencies()->setCurrent('EUR');
|
||||
expect(currencies()->getCurrent())->toBeInstanceOf(EUR::class);
|
||||
});
|
||||
|
||||
test('the current currency can be persisted', function () {
|
||||
currencies()->add([CZK::class, EUR::class]);
|
||||
|
||||
$store = [];
|
||||
$resolverCalled = false;
|
||||
|
||||
currencies()->storeCurrentUsing(function ($currency) use (&$store) {
|
||||
$store[] = $currency;
|
||||
});
|
||||
|
||||
currencies()->resolveCurrentUsing(function () use (&$resolverCalled, &$store) {
|
||||
$resolverCalled = true;
|
||||
|
||||
return last($store);
|
||||
});
|
||||
|
||||
currencies()->setCurrent('CZK');
|
||||
expect($store)->toBe(['CZK']);
|
||||
expect(currencies()->getCurrent()->code())->toBe('CZK');
|
||||
expect($resolverCalled)->toBeFalse();
|
||||
|
||||
currencies()->setCurrent('EUR');
|
||||
expect($store)->toBe(['CZK', 'EUR']);
|
||||
expect(currencies()->getCurrent()->code())->toBe('EUR');
|
||||
expect($resolverCalled)->toBeFalse();
|
||||
|
||||
currencies()->forgetCurrent();
|
||||
|
||||
expect(currencies()->getCurrent()->code())->toBe('EUR');
|
||||
expect($resolverCalled)->toBeTrue(); // got called
|
||||
});
|
||||
|
||||
test('individual currencies can be removed', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
expect(currencies()->all())->toHaveCount(2);
|
||||
|
||||
currencies()->remove('USD');
|
||||
|
||||
expect(currencies()->all())->toHaveCount(1);
|
||||
});
|
||||
|
||||
test('currencies can be cleared', function () {
|
||||
currencies()->clear();
|
||||
expect(currencies()->all())->toHaveCount(0);
|
||||
});
|
||||
|
||||
test('more currencies can be provided', function () {
|
||||
currencies()->add([CZK::class, EUR::class]);
|
||||
|
||||
expect(currencies()->all())->toHaveCount(3);
|
||||
});
|
||||
|
||||
test('duplicate currencies get overriden', function () {
|
||||
$customUSD = new USD(rate: 20);
|
||||
|
||||
currencies()->add($customUSD);
|
||||
|
||||
expect(currencies()->all())->toHaveCount(1);
|
||||
expect(currencies()->all())->toHaveKey('USD', $customUSD);
|
||||
});
|
||||
|
||||
test('the default currency can have any rate', function () {
|
||||
// This tests that the default currency doesn't have to have a rate of 1
|
||||
currencies()->add([CZK::class, EUR::class]);
|
||||
|
||||
expect(
|
||||
money(1500, 'CZK')->convertTo(EUR::class)->formatted()
|
||||
)->toBe('0.54 €');
|
||||
|
||||
currencies()->setDefault(CZK::class);
|
||||
|
||||
expect(
|
||||
money(1500, 'CZK')->convertTo(EUR::class)->formatted()
|
||||
)->toBe('0.54 €');
|
||||
});
|
||||
|
||||
test('the getCode method accepts any currency format', function () {
|
||||
expect(currencies()->getCode(USD::class))->toBe('USD');
|
||||
expect(currencies()->getCode(new USD))->toBe('USD');
|
||||
expect(currencies()->getCode('USD'))->toBe('USD');
|
||||
});
|
||||
|
||||
test('array currencies get converted to anonymous Currency objects', function () {
|
||||
currencies()->add((new CZK)->toArray());
|
||||
|
||||
expect(currencies()->all())->toHaveKey('CZK');
|
||||
});
|
||||
|
||||
test('add accepts any currency format', function () {
|
||||
currencies()->clear();
|
||||
|
||||
// Class instances
|
||||
currencies()->add($instance = new CZK);
|
||||
expect(currencies()->all())->toHaveKey('CZK', $instance);
|
||||
|
||||
// Anonymous class instances
|
||||
currencies()->add($gbp = new Currency(code: 'GBP', rate: 0.8, name: 'British Pound'));
|
||||
expect(currencies()->all())->toHaveKey('GBP', $gbp);
|
||||
|
||||
// Class names
|
||||
currencies()->add(USD::class);
|
||||
expect(currencies()->all())->toHaveKey('USD');
|
||||
|
||||
// Arrays
|
||||
currencies()->add((new CZK)->toArray());
|
||||
expect(currencies()->all())->toHaveKey('CZK');
|
||||
});
|
||||
|
||||
test('the add method accepts an array of named Currency instances', function () {
|
||||
currencies()->add([
|
||||
new CZK,
|
||||
new EUR,
|
||||
]);
|
||||
|
||||
expect(currencies()->all())->toHaveKeys(['CZK', 'EUR']);
|
||||
});
|
||||
|
||||
test('the add method accepts an array of anonymous Currency instances', function () {
|
||||
currencies()->add([
|
||||
new Currency(code: 'USD', rate: 1, name: 'United States Dollar'),
|
||||
new Currency(code: 'EUR', rate: 0.8, name: 'Euro'),
|
||||
]);
|
||||
|
||||
expect(currencies()->all())->toHaveKeys(['USD', 'EUR']);
|
||||
});
|
||||
|
||||
test('the add method accepts an array of Currency class strings', function () {
|
||||
currencies()->add([USD::class, EUR::class]);
|
||||
|
||||
expect(currencies()->all())->toHaveKeys(['USD', 'EUR']);
|
||||
});
|
||||
|
||||
test('the add method accepts an array of currency arrays', function () {
|
||||
currencies()->add([
|
||||
(new CZK)->toArray(),
|
||||
(new EUR)->toArray(),
|
||||
]);
|
||||
|
||||
expect(currencies()->all())->toHaveKeys(['USD', 'CZK', 'EUR']);
|
||||
});
|
||||
42
tests/Pest/CurrencyTest.php
Normal file
42
tests/Pest/CurrencyTest.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use ArchTech\Money\Currency;
|
||||
use ArchTech\Money\Exceptions\InvalidCurrencyException;
|
||||
use ArchTech\Money\Tests\Currencies\CZK;
|
||||
|
||||
test("a currency is invalid if it doesn't have a name", function () {
|
||||
pest()->expectException(InvalidCurrencyException::class);
|
||||
|
||||
new Currency(rate: 2.0, code: 'CZK');
|
||||
});
|
||||
|
||||
test("a currency is invalid if it doesn't have a code", function () {
|
||||
pest()->expectException(InvalidCurrencyException::class);
|
||||
|
||||
new Currency(rate: 2.0, name: 'Czech Crown');
|
||||
});
|
||||
|
||||
test('currencies can be serialized to JSON', function () {
|
||||
expect(json_encode(new CZK))->json()->toBe([
|
||||
'code' => 'CZK',
|
||||
'name' => 'Czech Crown',
|
||||
'rate' => 25,
|
||||
'prefix' => '',
|
||||
'suffix' => ' Kč',
|
||||
'mathDecimals' => 2,
|
||||
'displayDecimals' => 0,
|
||||
'rounding' => 2,
|
||||
'decimalSeparator' => ',',
|
||||
'thousandsSeparator' => '.',
|
||||
]);
|
||||
});
|
||||
|
||||
test('currencies can be created from JSON', function () {
|
||||
$original = new Currency(code: 'GBP', rate: 0.8, name: 'British Pound');
|
||||
|
||||
$json = json_encode($original);
|
||||
|
||||
$new = Currency::fromJson($json);
|
||||
|
||||
expect($original->toArray())->toBe($new->toArray());
|
||||
});
|
||||
48
tests/Pest/FormattingTest.php
Normal file
48
tests/Pest/FormattingTest.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
use ArchTech\Money\CurrencyManager;
|
||||
use ArchTech\Money\Currencies\USD;
|
||||
use ArchTech\Money\Currency;
|
||||
use ArchTech\Money\Money;
|
||||
use ArchTech\Money\Tests\Currencies\CZK;
|
||||
use ArchTech\Money\Tests\Currencies\EUR;
|
||||
|
||||
beforeEach(fn () => currencies()->add([CZK::class, EUR::class]));
|
||||
|
||||
test('prefixes are applied', function () {
|
||||
expect(Money::fromDecimal(10.00, USD::class)->formatted())->toBe('$10.00');
|
||||
});
|
||||
|
||||
test('suffixes are applied', function () {
|
||||
expect(Money::fromDecimal(10.00, CZK::class)->formatted())->toBe('10 Kč');
|
||||
});
|
||||
|
||||
test('decimals can be applied even if the decimal points are zero', function () {
|
||||
expect(Money::fromDecimal(10.00, CZK::class)->formatted())->toBe('10 Kč');
|
||||
|
||||
expect(Money::fromDecimal(10.00, EUR::class)->formatted())->toBe('10.00 €');
|
||||
});
|
||||
|
||||
test('decimals have a separator', function () {
|
||||
expect(Money::fromDecimal(10.34, EUR::class)->formatted())->toBe('10.34 €');
|
||||
|
||||
expect(Money::fromDecimal(10.34, CZK::class)->rawFormatted())->toBe('10,34 Kč');
|
||||
});
|
||||
|
||||
test('thousands have a separator', function () {
|
||||
currencies()->add(new Currency(
|
||||
code: 'FOO',
|
||||
name: 'Foo Currency',
|
||||
thousandsSeparator: ' ',
|
||||
));
|
||||
|
||||
expect(Money::fromDecimal(1234567.89, 'USD')->formatted())->toBe('$1,234,567.89');
|
||||
expect(Money::fromDecimal(1234567.89, 'EUR')->formatted())->toBe('1,234,567.89 €');
|
||||
expect(Money::fromDecimal(1234567.89, 'CZK')->formatted())->toBe('1.234.568 Kč');
|
||||
expect(Money::fromDecimal(1234567.89, 'FOO')->formatted())->toBe('1 234 567.89');
|
||||
});
|
||||
|
||||
test('the format method accepts overrides', function () {
|
||||
expect(Money::fromDecimal(10.45)->formatted(['decimalSeparator' => ',', 'prefix' => '$$$']))->toBe('$$$10,45');
|
||||
expect(Money::fromDecimal(10.45)->formatted(decimalSeparator: ',', suffix: ' USD'))->toBe('$10,45 USD');
|
||||
});
|
||||
53
tests/Pest/HelperTest.php
Normal file
53
tests/Pest/HelperTest.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
use ArchTech\Money\Currencies\USD;
|
||||
use ArchTech\Money\Money;
|
||||
use ArchTech\Money\Tests\Currencies\CZK;
|
||||
use ArchTech\Money\Tests\Currencies\EUR;
|
||||
|
||||
test('the currency helper can be used to fetch the current currency', function () {
|
||||
expect(currency())->toBe(currencies()->getCurrent());
|
||||
});
|
||||
|
||||
test('the currency helper can be used to fetch a specific currency using its code', function () {
|
||||
currencies()->add(EUR::class);
|
||||
|
||||
expect(currency('EUR'))->toBeInstanceOf(EUR::class);
|
||||
});
|
||||
|
||||
test('the currency helper can be used to fetch a specific currency using its class', function () {
|
||||
currencies()->add(EUR::class);
|
||||
|
||||
expect(currency(EUR::class))->toBeInstanceOf(EUR::class);
|
||||
});
|
||||
|
||||
test('the money helper creates a new Money instance', function () {
|
||||
expect(money(200))->toBeInstanceOf(Money::class);
|
||||
});
|
||||
|
||||
test('the money helper accepts a string currency', function () {
|
||||
currencies()->add([EUR::class, CZK::class]);
|
||||
|
||||
expect(money(200, 'EUR')->currency())->toBeInstanceOf(EUR::class);
|
||||
expect(money(200, 'CZK')->currency())->toBeInstanceOf(CZK::class);
|
||||
});
|
||||
|
||||
test('the money helper accepts a class currency', function () {
|
||||
currencies()->add([EUR::class, CZK::class]);
|
||||
|
||||
expect(money(200, EUR::class)->currency())->toBeInstanceOf(EUR::class);
|
||||
expect(money(200, CZK::class)->currency())->toBeInstanceOf(CZK::class);
|
||||
});
|
||||
|
||||
test('the money helper accepts a currency object', function () {
|
||||
currencies()->add([EUR::class, CZK::class]);
|
||||
|
||||
expect(money(200, new EUR)->currency())->toBeInstanceOf(EUR::class);
|
||||
expect(money(200, new CZK)->currency())->toBeInstanceOf(CZK::class);
|
||||
});
|
||||
|
||||
test('the money helper falls back to the default currency', function () {
|
||||
currencies()->add(EUR::class);
|
||||
|
||||
expect(money(200)->currency())->toBeInstanceOf(USD::class);
|
||||
});
|
||||
44
tests/Pest/MathTest.php
Normal file
44
tests/Pest/MathTest.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
use ArchTech\Money\CurrencyManager;
|
||||
use ArchTech\Money\Tests\Currencies\CZK;
|
||||
|
||||
test('money is rounded to its math decimals after each operation', function () {
|
||||
expect(
|
||||
money(33)->times(3.03)->value() // 0.9999
|
||||
)->toBe(100);
|
||||
});
|
||||
|
||||
test('operations use the math decimals even if the display decimals are different', function () {
|
||||
currencies()->add(CZK::class); // uses 0 display decimals
|
||||
|
||||
$money = money(33, 'CZK')->times(3); // 0.99
|
||||
expect($money->value())->toBe(99);
|
||||
expect($money->formatted())->toBe('1 Kč');
|
||||
|
||||
$money = money(33, 'CZK')->times(3.03); // 0.9999
|
||||
expect($money->value())->toBe(100);
|
||||
expect($money->formatted())->toBe('1 Kč');
|
||||
});
|
||||
|
||||
test('rounding is not applied between operations', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
// 99
|
||||
$money = money(33, 'CZK')->times(3);
|
||||
expect($money->value())->toBe(99);
|
||||
expect($money->rounded()->value())->toBe(100);
|
||||
expect($money->rounding())->toBe(1);
|
||||
|
||||
// 139
|
||||
$money = $money->add(40);
|
||||
expect($money->value())->toBe(139);
|
||||
expect($money->rounded()->value())->toBe(100);
|
||||
expect($money->rounding())->toBe(-39);
|
||||
|
||||
// 151
|
||||
$money = $money->add(12);
|
||||
expect($money->value())->toBe(151);
|
||||
expect($money->rounded()->value())->toBe(200);
|
||||
expect($money->rounding())->toBe(49);
|
||||
});
|
||||
232
tests/Pest/MoneyTest.php
Normal file
232
tests/Pest/MoneyTest.php
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
<?php
|
||||
|
||||
use ArchTech\Money\CurrencyManager;
|
||||
use ArchTech\Money\Currencies\USD;
|
||||
use ArchTech\Money\Currency;
|
||||
use ArchTech\Money\Money;
|
||||
use ArchTech\Money\Tests\Currencies\CZK;
|
||||
use ArchTech\Money\Tests\Currencies\EUR;
|
||||
|
||||
test('Money value is immutable', function () {
|
||||
pest()->expectError();
|
||||
|
||||
$money = money(100);
|
||||
|
||||
$money->value = 200;
|
||||
});
|
||||
|
||||
test('Money currency is immutable', function () {
|
||||
pest()->expectError();
|
||||
|
||||
$money = money(100);
|
||||
|
||||
$money->currency = 'EUR';
|
||||
});
|
||||
|
||||
test('money can be created from a decimal value', function () {
|
||||
$money = Money::fromDecimal(10.0, 'USD');
|
||||
|
||||
expect($money->value())->toBe(1000);
|
||||
});
|
||||
|
||||
test('money can be converted to decimals', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
$money = Money::fromDecimal(10.0, 'USD');
|
||||
expect($money->value())->toBe(1000);
|
||||
expect($money->decimal())->toBe(10.0);
|
||||
|
||||
$money = Money::fromDecimal(15.0, 'CZK');
|
||||
expect($money->value())->toBe(1500);
|
||||
expect($money->decimal())->toBe(15.0);
|
||||
});
|
||||
|
||||
test('money can be added in base value', function () {
|
||||
$money = money(100);
|
||||
$money = $money->add(200);
|
||||
|
||||
expect($money->value())->toBe(300);
|
||||
});
|
||||
|
||||
test('money can be added from another Money instance', function () {
|
||||
$money = money(100);
|
||||
$money = $money->addMoney(money(500));
|
||||
|
||||
expect($money->value())->toBe(600);
|
||||
});
|
||||
|
||||
test('money can be added from a Money instance with a different currency', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
$usd = Money::fromDecimal(10.0, 'USD');
|
||||
$czk = Money::fromDecimal(100.0, 'CZK'); // 4 USD
|
||||
|
||||
$usd = $usd->addMoney($czk);
|
||||
|
||||
expect($usd->decimal())->toBe(14.0);
|
||||
});
|
||||
|
||||
test('money can be subtracted in base value', function () {
|
||||
$money = money(300);
|
||||
$money = $money->subtract(200);
|
||||
|
||||
expect($money->value())->toBe(100);
|
||||
});
|
||||
|
||||
test('money can be subtracted by another Money instance', function () {
|
||||
$money = money(500);
|
||||
$money = $money->subtractMoney(money(100));
|
||||
|
||||
expect($money->value())->toBe(400);
|
||||
});
|
||||
|
||||
test('money can be subtracted by a Money instance with a different currency', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
$usd = Money::fromDecimal(10.0, 'USD');
|
||||
$czk = Money::fromDecimal(100.0, 'CZK'); // 4 USD
|
||||
|
||||
$usd = $usd->subtractMoney($czk);
|
||||
|
||||
expect($usd->decimal())->toBe(6.0);
|
||||
});
|
||||
|
||||
test('money can be multiplied', function () {
|
||||
expect(money(100)->multiplyBy(2.5)->value())->toBe(250);
|
||||
|
||||
expect(money(100)->times(2.5)->value())->toBe(250);
|
||||
});
|
||||
|
||||
test('money can be divided', function () {
|
||||
expect(money(100)->divideBy(10)->value())->toBe(10);
|
||||
});
|
||||
|
||||
test('fees can be added to and subtracted from money', function () {
|
||||
$money = Money::fromDecimal(10.0);
|
||||
|
||||
expect($money->addFee(0.1)->decimal())->toBe(11.0);
|
||||
expect($money->subtractFee(0.1)->decimal())->toBe(9.09); // 10/1.1
|
||||
});
|
||||
|
||||
test('taxes can be added and subtracted from money', function () {
|
||||
currencies()->add([CZK::class]);
|
||||
|
||||
expect(
|
||||
Money::fromDecimal(100.0, 'CZK')->addTax(0.21)->decimal()
|
||||
)->toBe(121.0);
|
||||
|
||||
expect(
|
||||
Money::fromDecimal(121.0, 'CZK')->subtractTax(0.21)->decimal()
|
||||
)->toBe(100.0);
|
||||
});
|
||||
|
||||
test('money can be converted to a different currency', function () {
|
||||
currencies()->add([CZK::class]);
|
||||
|
||||
$money = Money::fromDecimal(100.0);
|
||||
|
||||
expect($money->currency())->toBeInstanceOf(USD::class);
|
||||
expect($money->currency()->code())->toBe('USD');
|
||||
|
||||
$money = $money->convertTo(CZK::class);
|
||||
|
||||
expect($money->decimal())->toBe(2500.0);
|
||||
expect($money->currency())->toBeInstanceOf(CZK::class);
|
||||
expect($money->currency()->code())->toBe('CZK');
|
||||
});
|
||||
|
||||
test('money can be formatted', function () {
|
||||
expect(
|
||||
Money::fromDecimal(10.00, USD::class)->formatted()
|
||||
)->toBe('$10.00');
|
||||
});
|
||||
|
||||
test('money can be formatted without rounding', function () {
|
||||
currencies()->add([CZK::class]);
|
||||
|
||||
expect(
|
||||
Money::fromDecimal(10.34, CZK::class)->rawFormatted()
|
||||
)->toBe('10,34 Kč');
|
||||
});
|
||||
|
||||
test('converting money to a string returns the formatted string', function () {
|
||||
expect(
|
||||
(string) Money::fromDecimal(10.00, USD::class)
|
||||
)->toBe('$10.00');
|
||||
});
|
||||
|
||||
test('money can be converted to default currency value', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
$money = money(5000, CZK::class);
|
||||
|
||||
expect($money->valueInDefaultCurrency())->toBe(
|
||||
$money->convertTo(currencies()->getDefault())->value()
|
||||
);
|
||||
});
|
||||
|
||||
test('money can have rounding', function () {
|
||||
currencies()->add([CZK::class, EUR::class]);
|
||||
|
||||
expect(money(12340, 'CZK')->rounding())->toBe(-40);
|
||||
expect(money(12340, 'EUR')->rounding())->toBe(0);
|
||||
});
|
||||
|
||||
test('money can be rounded with a custom precision', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
expect(money(12340, 'CZK')->rounding())->toBe(-40);
|
||||
expect(money(12340, 'CZK')->rounded()->value())->toBe(12300);
|
||||
expect(money(12340, 'CZK')->rounded(3)->value())->toBe(12000);
|
||||
});
|
||||
|
||||
test('money can be compared', function () {
|
||||
expect(
|
||||
money(123)->equals(money(123))
|
||||
)->toBeTrue();
|
||||
|
||||
expect(
|
||||
money(123)->equals(money(456))
|
||||
)->toBeFalse();
|
||||
});
|
||||
|
||||
test('money can be compared with different currencies', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
expect(
|
||||
money(123, 'USD')->equals(money(123)->convertTo(CZK::class))
|
||||
)->toBeTrue();
|
||||
});
|
||||
|
||||
test('the is method compares both the value and the currency', function () {
|
||||
currencies()->add([CZK::class, EUR::class]);
|
||||
|
||||
expect(
|
||||
money(123, 'EUR')->is(money(123)->convertTo(CZK::class))
|
||||
)->toBeFalse();
|
||||
|
||||
expect(
|
||||
money(123, 'EUR')->is(money(123)->convertTo(CZK::class)->convertTo(EUR::class))
|
||||
)->toBeFalse();
|
||||
});
|
||||
|
||||
test('money can be serialized to JSON', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
$money = Money::fromDecimal(22, 'CZK');
|
||||
|
||||
expect(json_encode($money))->json()->toBe(['value' => 2200, 'currency' => 'CZK']);
|
||||
expect($money->toJson())->json()->toBe(['value' => 2200, 'currency' => 'CZK']);
|
||||
});
|
||||
|
||||
test('money can be instantiated from JSON', function () {
|
||||
currencies()->add(CZK::class);
|
||||
|
||||
$original = Money::fromDecimal(22, 'CZK');
|
||||
|
||||
$json = json_encode($original);
|
||||
|
||||
$new = Money::fromJson($json)->toArray();
|
||||
|
||||
expect($new)->toBe($original->toArray());
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue