From fdd6c30719b59c60f4b59de01fe0d30e7d0f1285 Mon Sep 17 00:00:00 2001 From: Mark Scherer Date: Sun, 11 Oct 2026 16:29:14 +0200 Subject: [PATCH] Require PHP 8.2 and update the dev tooling PHP 8.1 has been out of security support since the end of 2025. The floor stops at 8.2 because dereuromark/cakephp-decimal supports 8.2 and should keep receiving new releases of this library. - PHPUnit ^11.5 || ^12 || ^13, the 10.x line was only needed for 8.1. - php-collective/code-sniffer 0.2 to 0.6. The new rules want attributes imported and docblock types that agree with the native hint, so the operand docblocks now say self like the signatures do. - CI runs 8.2, 8.3, 8.4 and 8.5 on ubuntu-latest. - The Docker image no longer downloads PHPUnit 10.4 and PHPStan 1.10 phars. The Makefile runs the Composer scripts and never used them. - composer.json gains keywords and support links. --- .docker/Dockerfile | 9 +------ .env | 4 +-- .github/workflows/ci.yml | 18 ++++++------- README.md | 5 ++-- compose.yaml | 4 +-- composer.json | 18 ++++++++++--- phpunit.xml.dist | 2 ++ src/Decimal.php | 30 +++++++++++----------- tests/DecimalTest.php | 55 ++++++++++++++++++++-------------------- 9 files changed, 75 insertions(+), 70 deletions(-) diff --git a/.docker/Dockerfile b/.docker/Dockerfile index dd46470..d7bc22c 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,14 +1,7 @@ -ARG PHP_VERSION=8.2 -ARG PHPUNIT_VERSION=10.4.0 -ARG PHPSTAN_VERSION=1.10.38 +ARG PHP_VERSION=8.5 FROM php:${PHP_VERSION}-cli-alpine COPY --from=composer /usr/bin/composer /usr/bin/composer -ARG PHPUNIT_VERSION -ARG PHPSTAN_VERSION - RUN docker-php-ext-install bcmath && docker-php-ext-enable bcmath -RUN wget -O phpunit https://phar.phpunit.de/phpunit-${PHPUNIT_VERSION}.phar && chmod +x phpunit -RUN wget -O phpstan https://github.com/phpstan/phpstan/releases/download/${PHPSTAN_VERSION}/phpstan.phar && chmod +x phpstan diff --git a/.env b/.env index af97ce2..93ca64f 100644 --- a/.env +++ b/.env @@ -1,3 +1 @@ -PHP_VERSION=8.2 -PHPUNIT_VERSION=10.4.0 -PHPSTAN_VERSION=1.10.38 +PHP_VERSION=8.5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 191fdc4..e40c7f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,14 +9,14 @@ on: jobs: testsuite: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest strategy: fail-fast: false matrix: - php-version: ['8.1', '8.3', '8.5'] + php-version: ['8.2', '8.3', '8.4', '8.5'] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -32,29 +32,29 @@ jobs: - name: Run PHPUnit run: | - if [[ ${{ matrix.php-version }} == '8.1' ]]; then + if [[ ${{ matrix.php-version }} == '8.2' ]]; then vendor/bin/phpunit --coverage-clover=coverage.xml else vendor/bin/phpunit fi - name: Code Coverage Report - if: success() && matrix.php-version == '8.1' - uses: codecov/codecov-action@v4 + if: success() && matrix.php-version == '8.2' + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} validation: name: Coding Standard & Static Analysis - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' + php-version: '8.2' extensions: mbstring, intl, bcmath coverage: none diff --git a/README.md b/README.md index 518f735..9193433 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CI](https://github.com/php-collective/decimal-object/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/php-collective/decimal-object/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/php-collective/decimal-object/branch/master/graph/badge.svg?token=L1thFB9nOG)](https://codecov.io/gh/php-collective/decimal-object) [![Latest Stable Version](https://poser.pugx.org/php-collective/decimal-object/v/stable.svg)](https://packagist.org/packages/php-collective/decimal-object) -[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%208.1-8892BF.svg)](https://php.net/) +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%208.2-8892BF.svg)](https://php.net/) [![PHPStan](https://img.shields.io/badge/PHPStan-level%208-brightgreen.svg?style=flat)](https://phpstan.org/) [![License](https://poser.pugx.org/php-collective/decimal-object/license)](https://packagist.org/packages/php-collective/decimal-object) @@ -26,7 +26,7 @@ Monetary values themselves could be handled also with [brick/money](https://gith For details see the [wiki](https://github.com/php-collective/decimal-object/wiki). -Note: If you are looking for pre PHP 8.1 versions, check out the [legacy library](https://github.com/spryker/decimal-object). +Note: PHP 8.1 is covered by the 1.3 releases. For anything older, check out the [legacy library](https://github.com/spryker/decimal-object). ## Features @@ -40,6 +40,7 @@ Note: If you are looking for pre PHP 8.1 versions, check out the [legacy library ### Requirements +- PHP 8.2+ - `bcmath` PHP extension enabled ### Composer (preferred) diff --git a/compose.yaml b/compose.yaml index 84edd30..7d9c008 100644 --- a/compose.yaml +++ b/compose.yaml @@ -6,9 +6,7 @@ services: context: . dockerfile: .docker/Dockerfile args: - PHP_VERSION: "${PHP_VERSION:-8.2}" - PHPUNIT_VERSION: "${PHPUNIT_VERSION:-10.4.0}" - PHPSTAN_VERSION: "${PHPSTAN_VERSION:-1.10.38}" + PHP_VERSION: "${PHP_VERSION:-8.5}" volumes: - ./:/code working_dir: /code diff --git a/composer.json b/composer.json index ae80adf..c37719e 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,14 @@ "description": "PHP decimal handling as value object", "license": "MIT", "type": "library", + "keywords": [ + "decimal", + "value-object", + "bcmath", + "precision", + "arbitrary-precision", + "math" + ], "authors": [ { "name": "The PHP Collective", @@ -13,15 +21,19 @@ "homepage": "https://spryker.com" } ], + "support": { + "issues": "https://github.com/php-collective/decimal-object/issues", + "source": "https://github.com/php-collective/decimal-object" + }, "require": { - "php": ">=8.1", + "php": ">=8.2", "ext-bcmath": "*", "ext-json": "*" }, "require-dev": { - "php-collective/code-sniffer": "^0.2.1", + "php-collective/code-sniffer": "^0.6.8", "phpstan/phpstan": "^2.0.0", - "phpunit/phpunit": "^10.5.45 || ^11.0.0 || ^12.0.0 || ^13.0.0" + "phpunit/phpunit": "^11.5.0 || ^12.0.0 || ^13.0.0" }, "minimum-stability": "stable", "prefer-stable": true, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ef3d67a..eca8d3f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,7 @@ diff --git a/src/Decimal.php b/src/Decimal.php index ec10482..e3cba1a 100644 --- a/src/Decimal.php +++ b/src/Decimal.php @@ -162,7 +162,7 @@ public static function create(object|string|float|int $value, ?int $scale = null * * This method is equivalent to the `==` operator. * - * @param static|string|float|int $value + * @param self|string|float|int $value * * @return bool TRUE if this decimal is considered equal to the given value. * Equal decimal values tie-break on precision. @@ -173,7 +173,7 @@ public function equals(self|string|float|int $value): bool } /** - * @param static|string|float|int $value + * @param self|string|float|int $value * * @return bool */ @@ -183,7 +183,7 @@ public function greaterThan(self|string|float|int $value): bool } /** - * @param static|string|float|int $value + * @param self|string|float|int $value * * @return bool */ @@ -193,7 +193,7 @@ public function lessThan(self|string|float|int $value): bool } /** - * @param static|string|float|int $value + * @param self|string|float|int $value * * @return bool */ @@ -205,7 +205,7 @@ public function greaterThanOrEquals(self|string|float|int $value): bool /** * @deprecated Use {@link greaterThanOrEquals()} instead. * - * @param static|string|float|int $value + * @param self|string|float|int $value * * @return bool */ @@ -215,7 +215,7 @@ public function greatherThanOrEquals(self|string|float|int $value): bool } /** - * @param static|string|float|int $value + * @param self|string|float|int $value * * @return bool */ @@ -232,7 +232,7 @@ public function lessThanOrEquals(self|string|float|int $value): bool * - `0` if the instance is equal to $value, or * - `1` if the instance is greater than $value. * - * @param static|string|float|int $value + * @param self|string|float|int $value * * @return int */ @@ -247,7 +247,7 @@ public function compareTo(self|string|float|int $value): int /** * Add $value to this Decimal and return the sum as a new Decimal. * - * @param static|string|float|int $value + * @param self|string|float|int $value * @param int|null $scale Decimal places in the result. Omit to enable auto-detection. * * @return static @@ -281,7 +281,7 @@ protected function resultScale(self $a, self $b, ?int $scale = null): int * Subtract $value from this Decimal and return the difference as a new * Decimal. * - * @param static|string|float|int $value + * @param self|string|float|int $value * @param int|null $scale Decimal places in the result. Omit to enable auto-detection. * * @return static @@ -389,12 +389,12 @@ public function isPositive(): bool /** * Multiply this Decimal by $value and return the product as a new Decimal. * - * @param static|string|float|int $value + * @param self|string|float|int $value * @param int|null $scale Decimal places in the result. Omit to enable auto-detection. * * @return static */ - public function multiply(self|string|int|float $value, ?int $scale = null): static + public function multiply(self|string|float|int $value, ?int $scale = null): static { $decimal = static::create($value); if ($scale === null) { @@ -407,14 +407,14 @@ public function multiply(self|string|int|float $value, ?int $scale = null): stat /** * Divide this Decimal by $value and return the quotient as a new Decimal. * - * @param static|string|float|int $value + * @param self|string|float|int $value * @param int $scale Decimal places in the result * * @throws \DivisionByZeroError if $value is zero. * * @return static */ - public function divide(self|string|int|float $value, int $scale): static + public function divide(self|string|float|int $value, int $scale): static { $decimal = static::create($value); if ($decimal->isZero()) { @@ -427,7 +427,7 @@ public function divide(self|string|int|float $value, int $scale): static /** * This method is equivalent to the ** operator. * - * @param static|string|int $exponent + * @param self|string|int $exponent * @param int|null $scale Decimal places in the result. Omit to enable auto-detection. * * @return static @@ -460,7 +460,7 @@ public function sqrt(?int $scale = null): static /** * This method is equivalent to the % operator. * - * @param static|string|int $value + * @param self|string|int $value * @param int|null $scale Decimal places in the result. Omit to enable auto-detection. * * @return static diff --git a/tests/DecimalTest.php b/tests/DecimalTest.php index e235cde..bf863c8 100644 --- a/tests/DecimalTest.php +++ b/tests/DecimalTest.php @@ -12,6 +12,7 @@ use DivisionByZeroError; use InvalidArgumentException; use PhpCollective\DecimalObject\Decimal; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Stringable; use TypeError; @@ -24,7 +25,7 @@ class DecimalTest extends TestCase * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('baseProvider')] + #[DataProvider('baseProvider')] public function testNewObject(mixed $value, string $expected): void { $decimal = new Decimal($value); @@ -50,7 +51,7 @@ public function testNewObjectScientific(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('baseProvider')] + #[DataProvider('baseProvider')] public function testCreate(mixed $value, string $expected): void { $decimal = Decimal::create($value); @@ -142,7 +143,7 @@ public function __toString(): string * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('invalidValuesProvider')] + #[DataProvider('invalidValuesProvider')] public function testNewObjectWithInvalidValueThrowsException(mixed $value): void { $this->expectException(InvalidArgumentException::class); @@ -169,7 +170,7 @@ public static function invalidValuesProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('truncateProvider')] + #[DataProvider('truncateProvider')] public function testTruncate(mixed $input, int $scale, string $expected): void { $decimal = Decimal::create($input); @@ -197,7 +198,7 @@ public static function truncateProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('integerProvider')] + #[DataProvider('integerProvider')] public function testIsInteger(mixed $value, bool $expected): void { $decimal = Decimal::create($value); @@ -229,7 +230,7 @@ public static function integerProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('zeroProvider')] + #[DataProvider('zeroProvider')] public function testIsZero(mixed $value, bool $expected): void { $decimal = Decimal::create($value); @@ -260,7 +261,7 @@ public static function zeroProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('compareZeroProvider')] + #[DataProvider('compareZeroProvider')] public function testIsPositive(mixed $input, int $expected): void { $decimal = Decimal::create($input); @@ -273,7 +274,7 @@ public function testIsPositive(mixed $input, int $expected): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('compareZeroProvider')] + #[DataProvider('compareZeroProvider')] public function testIsNegative(mixed $input, int $expected): void { $decimal = Decimal::create($input); @@ -307,7 +308,7 @@ public static function compareZeroProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('scaleProvider')] + #[DataProvider('scaleProvider')] public function testScale(mixed $input, int $expected): void { $decimal = Decimal::create($input); @@ -338,7 +339,7 @@ public static function scaleProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('scientificProvider')] + #[DataProvider('scientificProvider')] public function testToScientific(mixed $value, string $expected): void { $decimal = Decimal::create($value); @@ -411,7 +412,7 @@ public function testToFloat(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('bigFloatDataProvider')] + #[DataProvider('bigFloatDataProvider')] public function testToFloatForBigDecimalThrowsAnException(string $value): void { $decimal = Decimal::create($value); @@ -450,7 +451,7 @@ public function testToInt(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('bigIntDataProvider')] + #[DataProvider('bigIntDataProvider')] public function testToIntForBigIntThrowsAnException(string $value): void { $decimal = Decimal::create($value); @@ -605,7 +606,7 @@ public function testEquals(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('roundProvider')] + #[DataProvider('roundProvider')] public function testRound(mixed $value, int $scale, string $expected): void { $decimal = Decimal::create($value); @@ -664,7 +665,7 @@ public static function roundProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('floorProvider')] + #[DataProvider('floorProvider')] public function testFloor(mixed $value, string $expected): void { $decimal = Decimal::create($value); @@ -717,7 +718,7 @@ public static function floorProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('ceilProvider')] + #[DataProvider('ceilProvider')] public function testCeil(mixed $value, string $expected): void { $decimal = Decimal::create($value); @@ -770,7 +771,7 @@ public static function ceilProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('compareProvider')] + #[DataProvider('compareProvider')] public function testGreaterThan(mixed $a, mixed $b, int $expected): void { $decimal = Decimal::create($a); @@ -784,7 +785,7 @@ public function testGreaterThan(mixed $a, mixed $b, int $expected): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('compareProvider')] + #[DataProvider('compareProvider')] public function testLessThan(mixed $a, mixed $b, int $expected): void { $decimal = Decimal::create($a); @@ -798,7 +799,7 @@ public function testLessThan(mixed $a, mixed $b, int $expected): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('compareProvider')] + #[DataProvider('compareProvider')] public function testGreaterEquals(mixed $a, mixed $b, int $expected): void { $decimal = Decimal::create($a); @@ -812,7 +813,7 @@ public function testGreaterEquals(mixed $a, mixed $b, int $expected): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('compareProvider')] + #[DataProvider('compareProvider')] public function testLessEquals(mixed $a, mixed $b, int $expected): void { $decimal = Decimal::create($a); @@ -876,7 +877,7 @@ public function testSubtract(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('multiplicationProvider')] + #[DataProvider('multiplicationProvider')] public function testMultiply(mixed $a, mixed $b, ?int $scale, string $expected): void { $decimal = Decimal::create($a); @@ -915,7 +916,7 @@ public static function multiplicationProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('multiplicationLegacyProvider')] + #[DataProvider('multiplicationLegacyProvider')] public function testMultiplyLegacy(mixed $a, mixed $b, ?int $scale, string $expected): void { $decimal = Decimal::create($a); @@ -940,7 +941,7 @@ public static function multiplicationLegacyProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('divisionProvider')] + #[DataProvider('divisionProvider')] public function testDivide(mixed $a, mixed $b, int $scale, string $expected): void { $decimal = Decimal::create($a); @@ -1056,7 +1057,7 @@ public function testPrecisionLossFail(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('normalizationProvider')] + #[DataProvider('normalizationProvider')] public function testNewObjectNormalization(mixed $value, string $expected): void { $this->assertSame($expected, (string)new Decimal($value)); @@ -1099,7 +1100,7 @@ public static function normalizationProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('nonFiniteProvider')] + #[DataProvider('nonFiniteProvider')] public function testNewObjectNonFiniteFloat(float $value): void { $this->expectException(InvalidArgumentException::class); @@ -1185,7 +1186,7 @@ public function testNoNegativeZero(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('roundModeProvider')] + #[DataProvider('roundModeProvider')] public function testRoundMode(string $value, int $scale, int $mode, string $expected): void { $this->assertSame($expected, (string)(new Decimal($value))->round($scale, $mode)); @@ -1233,7 +1234,7 @@ public function testRoundNegativeScale(): void * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('roundInvalidModeProvider')] + #[DataProvider('roundInvalidModeProvider')] public function testRoundInvalidMode(string $value): void { $this->expectException(InvalidArgumentException::class); @@ -1258,7 +1259,7 @@ public static function roundInvalidModeProvider(): array * * @return void */ - #[\PHPUnit\Framework\Attributes\DataProvider('scientificEdgeProvider')] + #[DataProvider('scientificEdgeProvider')] public function testToScientificEdgeCases(string $value, string $expected): void { $decimal = new Decimal($value);