diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml index 86eddf4..2db0b6e 100644 --- a/.github/workflows/php-cs-fixer.yml +++ b/.github/workflows/php-cs-fixer.yml @@ -8,7 +8,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: ${{ github.head_ref }} @@ -16,7 +16,9 @@ jobs: run: composer install -n --prefer-dist - name: Run PHP CS Fixer - run: composer format + uses: docker://oskarstark/php-cs-fixer-ga + with: + args: --config=.php-cs-fixer.dist.php --allow-risky=yes - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v4 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index e6ef17b..fcf4f45 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -32,7 +32,7 @@ jobs: coverage: none - name: Install dependencies - run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest + run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction - name: Execute tests run: vendor/bin/phpunit diff --git a/README.md b/README.md index fef9624..dbc1e50 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ to the desired needs of your business. - [Modulus](#modulus) - [State & Comparison](#state--comparison) - [Absolute & opposite values](#absolute--opposite-values) + - [Limiting values](#limiting-values) - [Rounding](#rounding) - [Immutable & Chaining](#immutable--chaining) - [Extensibility](#extensibility) @@ -191,6 +192,28 @@ $absolute = $number->opposite(); $abs = $number->opp(); ``` +### Limiting values +To make sure the current number is not higher or lower than expected: + +```php +$number = new Number('200'); + +// $result will be 250 +$result = $number->min('250'); + +// $result will be 100 +$result = $number->max('100'); +``` + +To use a min and max 'clamp' at the same time: + +```php +$number = new Number('200'); + +// $result will be 150 +$result = $number->clamp('100', '150'); +``` + ### Rounding To round the current number instance, the following methods are available: diff --git a/composer.json b/composer.json index 038143a..d2fd22c 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,11 @@ "format": "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "phpro/grumphp": true, + "ocramius/package-versions": true + } }, "minimum-stability": "dev", "prefer-stable": true diff --git a/src/AbstractNumber.php b/src/AbstractNumber.php index ec17d7e..beea2d6 100644 --- a/src/AbstractNumber.php +++ b/src/AbstractNumber.php @@ -298,6 +298,54 @@ public function opp(): self return $this->opposite(); } + /** + * Prevent the current value to be less than the given value. + * + * @param AbstractNumber|string|float|int $value + */ + public function min($value = null): self + { + $value = $this->getNumberFromInput($value); + + if ($this->isLessThan($value)) { + return $this->init((string) $value); + } + + return $this; + } + + /** + * Prevent the current value to be more than the given value. + * + * @param AbstractNumber|string|float|int $value + */ + public function max($value = null): self + { + $value = $this->getNumberFromInput($value); + + if ($this->isGreaterThan($value)) { + return $this->init((string) $value); + } + + return $this; + } + + /** + * Put a clamp on the current value. + * + * @param AbstractNumber|string|float|int $min + * @param AbstractNumber|string|float|int $max + */ + public function clamp($min, $max): self + { + $result = $this; + + $result = $result->min($min); + $result = $result->max($max); + + return $this->init((string) $result); + } + /** * Return boolean if the current value is a positive number. */ diff --git a/tests/NumberTest.php b/tests/NumberTest.php index 4090f05..82609e0 100644 --- a/tests/NumberTest.php +++ b/tests/NumberTest.php @@ -488,6 +488,34 @@ public function testOpposite() $this->assertEquals('-0.3000', Number::create('0.3000')->opposite()->toString()); } + public function testMin() + { + $number = new Number('200'); + + $this->assertEquals('200.000', $number->min('200')); + $this->assertEquals('200.000', $number->min('150')); + $this->assertEquals('250.000', $number->min('250')); + } + + public function testMax() + { + $number = new Number('200'); + + $this->assertEquals('200.000', $number->max('200')); + $this->assertEquals('150.000', $number->max('150')); + $this->assertEquals('200.000', $number->max('250')); + } + + public function testClamp() + { + $number = new Number('200'); + + $this->assertEquals('200.000', $number->clamp('100', '200')); + $this->assertEquals('200.000', $number->clamp('100', '300')); + $this->assertEquals('100.000', $number->clamp('50', '100')); + $this->assertEquals('250.000', $number->clamp('250', '300')); + } + public function testIsPositive(): void { $this->assertTrue((new Number('200'))->isPositive());