77 lines
2.4 KiB
PHP
77 lines
2.4 KiB
PHP
<?php
|
|
|
|
use AKSRT\Ledger\AssetAmount;
|
|
use AKSRT\Ledger\AssetType;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class AssetAmountTest extends TestCase {
|
|
#[DataProvider('validBalanceProvider')]
|
|
public function test_balance_parses_exact_decimal_strings(string $input, int $minor, string $decimal): void {
|
|
$amount = AssetAmount::balance($input);
|
|
self::assertSame(AssetType::BALANCE, $amount->asset());
|
|
self::assertSame($minor, $amount->minor());
|
|
self::assertSame($decimal, $amount->decimal());
|
|
}
|
|
|
|
public static function validBalanceProvider(): array {
|
|
return [
|
|
'zero' => ['0', 0, '0.00'],
|
|
'one decimal' => ['12.3', 1230, '12.30'],
|
|
'two decimals' => ['12.34', 1234, '12.34'],
|
|
'integer' => ['999', 99900, '999.00'],
|
|
];
|
|
}
|
|
|
|
#[DataProvider('invalidBalanceProvider')]
|
|
public function test_balance_rejects_non_canonical_input(string $input): void {
|
|
$this->expectException(InvalidArgumentException::class);
|
|
AssetAmount::balance($input);
|
|
}
|
|
|
|
public static function invalidBalanceProvider(): array {
|
|
return [
|
|
'negative' => ['-1.00'],
|
|
'float precision' => ['1.001'],
|
|
'scientific notation' => ['1e2'],
|
|
'leading zero' => ['01.00'],
|
|
'leading decimal' => ['.50'],
|
|
'trailing decimal' => ['1.'],
|
|
'plus sign' => ['+1.00'],
|
|
'comma' => ['1,00'],
|
|
'empty' => [''],
|
|
];
|
|
}
|
|
|
|
public function test_balance_rejects_integer_overflow(): void {
|
|
$this->expectException(InvalidArgumentException::class);
|
|
AssetAmount::balance((string) PHP_INT_MAX . '.99');
|
|
}
|
|
|
|
public function test_points_are_integer_minor_units(): void {
|
|
self::assertSame(37, AssetAmount::points(37)->minor());
|
|
self::assertSame('37', AssetAmount::points(37)->decimal());
|
|
}
|
|
|
|
public function test_negative_points_are_rejected(): void {
|
|
$this->expectException(InvalidArgumentException::class);
|
|
AssetAmount::points(-1);
|
|
}
|
|
|
|
public function test_balance_minor_helpers_do_not_use_floats(): void {
|
|
self::assertSame(1234, AssetAmount::balance_minor('12.34'));
|
|
self::assertSame('12.34', AssetAmount::decimal_from_minor(1234));
|
|
}
|
|
|
|
public function test_percentage_rounds_half_up_in_minor_units(): void {
|
|
self::assertSame(266, AssetAmount::percentage(333, 80));
|
|
self::assertSame(1, AssetAmount::percentage(1, 50));
|
|
self::assertSame(0, AssetAmount::percentage(1, 49));
|
|
}
|
|
|
|
public function test_percentage_rejects_out_of_range_values(): void {
|
|
$this->expectException(InvalidArgumentException::class);
|
|
AssetAmount::percentage(100, 101);
|
|
}
|
|
}
|