From d1dcf5fdd25d5bddf8aa5f2c56c75ed2c98116b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Sun, 4 Oct 2020 11:07:14 +0200 Subject: [PATCH] Enhancement: Implement DataProvider\FloatProvider --- .github/workflows/integrate.yaml | 4 +- CHANGELOG.md | 11 +- Makefile | 4 +- README.md | 13 ++ phpstan-baseline.neon | 115 ++++++++++++ psalm-baseline.xml | 14 ++ src/DataProvider/FloatProvider.php | 105 +++++++++++ test/Unit/DataProvider/FloatProviderTest.php | 182 +++++++++++++++++++ 8 files changed, 442 insertions(+), 6 deletions(-) create mode 100644 src/DataProvider/FloatProvider.php create mode 100644 test/Unit/DataProvider/FloatProviderTest.php diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml index 91842a82..2976e8a8 100644 --- a/.github/workflows/integrate.yaml +++ b/.github/workflows/integrate.yaml @@ -10,8 +10,8 @@ on: # yamllint disable-line rule:truthy env: ERGEBNIS_BOT_NAME: "ergebnis-bot" - MIN_COVERED_MSI: 93 - MIN_MSI: 91 + MIN_COVERED_MSI: 94 + MIN_MSI: 92 PHP_EXTENSIONS: "mbstring" jobs: diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c6111ac..6619842c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased -For a full diff see [`1.1.0...main`][1.1.0...main]. +For a full diff see [`1.2.0...main`][1.2.0...main]. + +## [`1.2.0`][1.2.0] + +For a full diff see [`1.1.0...1.2.0`][1.1.0...1.2.0]. ### Added @@ -14,6 +18,7 @@ For a full diff see [`1.1.0...main`][1.1.0...main]. * Added `DataProvider\NullProvider` ([#327]), by [@localheinz] * Added `DataProvider\StringProvider` ([#328]), by [@localheinz] * Added `DataProvider\IntProvider` ([#335]), by [@localheinz] +* Added `DataProvider\FloatProvider` ([#341]), by [@localheinz] * ### Changed @@ -109,7 +114,8 @@ For a full diff see [`0.7.0...0.8.0`][0.7.0...0.8.0]. [0.9.1...1.0.0]: https://github.com/ergebnis/test-util/compare/0.9.1...1.0.0 [1.0.0...1.0.1]: https://github.com/ergebnis/test-util/compare/1.0.0...1.0.1 [1.0.1...1.1.0]: https://github.com/ergebnis/test-util/compare/1.0.1...1.1.0 -[1.1.0...main]: https://github.com/ergebnis/test-util/compare/1.1.0...main +[1.1.0...1.2.0]: https://github.com/ergebnis/test-util/compare/1.1.0...1.2.0 +[1.2.0...main]: https://github.com/ergebnis/test-util/compare/1.2.0...main [#118]: https://github.com/ergebnis/test-util/pull/118 [#119]: https://github.com/ergebnis/test-util/pull/119 @@ -124,6 +130,7 @@ For a full diff see [`0.7.0...0.8.0`][0.7.0...0.8.0]. [#328]: https://github.com/ergebnis/test-util/pull/328 [#334]: https://github.com/ergebnis/test-util/pull/334 [#335]: https://github.com/ergebnis/test-util/pull/335 +[#341]: https://github.com/ergebnis/test-util/pull/341 [@ergebnis]: https://github.com/ergebnis [@localheinz]: https://github.com/localheinz diff --git a/Makefile b/Makefile index 5b1b4b1e..76d8857b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -MIN_COVERED_MSI:=93 -MIN_MSI:=91 +MIN_COVERED_MSI:=94 +MIN_MSI:=92 .PHONY: it it: coding-standards static-code-analysis tests ## Runs the coding-standards, static-code-analysis, and tests targets diff --git a/README.md b/README.md index c6e929a8..06f451c3 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ In addition to the assertions made available by extending from `PHPUnit\Framewor This package provides the following generic data providers: * [`Ergebnis\Test\Util\DataProvider\BoolProvider`](https://github.com/ergebnis/test-util#dataproviderboolprovider) +* [`Ergebnis\Test\Util\DataProvider\FloatProvider`](https://github.com/ergebnis/test-util#dataproviderfloatprovider) * [`Ergebnis\Test\Util\DataProvider\IntProvider`](https://github.com/ergebnis/test-util#dataproviderintprovider) * [`Ergebnis\Test\Util\DataProvider\NullProvider`](https://github.com/ergebnis/test-util#dataprovidernullprovider) * [`Ergebnis\Test\Util\DataProvider\StringProvider`](https://github.com/ergebnis/test-util#dataproviderstringprovider) @@ -143,6 +144,18 @@ final class ExampleTest extends Framework\TestCase For examples, see [`Ergebnis\Test\Util\Test\Unit\DataProvider\BoolProviderTest`](test/Unit/DataProvider/BoolProviderTest.php). +#### `DataProvider\FloatProvider` + +* `arbitrary()` provides arbitrary `float`s +* `greaterThanOne()` provides `int`s greater than `1.0` +* `greaterThanZero()` provides `int`s greater than `0.0` +* `lessThanOne()` provides `int`s less than `1.0` +* `lessThanZero()` provides `int`s less than `0.0` +* `one()` provides `1.0` +* `zero()` provides `0.0` + +For examples, see [`Ergebnis\Test\Util\Test\Unit\DataProvider\FloatProviderTest`](test/Unit/DataProvider/FloatProviderTest.php). + #### `DataProvider\IntProvider` * `arbitrary()` provides arbitrary `int`s diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 805f150d..d200dbf4 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -115,6 +115,121 @@ parameters: count: 1 path: src/DataProvider/BoolProvider.php + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:faker\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassesAreAbstractOrFinal\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Parameter \\#1 \\$argument of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" + count: 2 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassesHaveTests\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Call to an undefined static method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertEmpty\\(\\)\\.$#" + count: 2 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassyConstructsSatisfySpecification\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassExists\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Call to an undefined static method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertTrue\\(\\)\\.$#" + count: 11 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassExtends\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassImplementsInterface\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassIsAbstract\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassIsFinal\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassSatisfiesSpecification\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertClassUsesTrait\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Call to an undefined static method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertContains\\(\\)\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertInterfaceExists\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertInterfaceExtends\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertInterfaceSatisfiesSpecification\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertTraitExists\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:assertTraitSatisfiesSpecification\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:provideDataForValues\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:provideDataForValuesWhere\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + + - + message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\FloatProvider\\:\\:provideDataForValuesWhereNot\\(\\) is protected, but since the containing class is final, it can be private\\.$#" + count: 1 + path: src/DataProvider/FloatProvider.php + - message: "#^Method Ergebnis\\\\Test\\\\Util\\\\DataProvider\\\\IntProvider\\:\\:faker\\(\\) is protected, but since the containing class is final, it can be private\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index b0e83ef5..88062c7d 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -10,6 +10,20 @@ true === $value + + + -1 * $faker->randomFloat(null, 1.01) + + + \Generator<string, array{0: float}> + \Generator<string, array{0: float}> + \Generator<string, array{0: float}> + \Generator<string, array{0: float}> + \Generator<string, array{0: float}> + \Generator<string, array{0: float}> + \Generator<string, array{0: float}> + + \Generator<string, array{0: int}> diff --git a/src/DataProvider/FloatProvider.php b/src/DataProvider/FloatProvider.php new file mode 100644 index 00000000..2b76c898 --- /dev/null +++ b/src/DataProvider/FloatProvider.php @@ -0,0 +1,105 @@ + + */ + public static function arbitrary(): \Generator + { + yield from self::provideDataForValues(self::values()); + } + + /** + * @return \Generator + */ + public static function lessThanZero(): \Generator + { + yield from self::provideDataForValuesWhere(self::values(), static function (float $value): bool { + return 0.0 > $value; + }); + } + + /** + * @return \Generator + */ + public static function zero(): \Generator + { + yield from self::provideDataForValuesWhere(self::values(), static function (float $value): bool { + return 0.0 === $value; + }); + } + + /** + * @return \Generator + */ + public static function greaterThanZero(): \Generator + { + yield from self::provideDataForValuesWhere(self::values(), static function (float $value): bool { + return 0.0 < $value; + }); + } + + /** + * @return \Generator + */ + public static function lessThanOne(): \Generator + { + yield from self::provideDataForValuesWhere(self::values(), static function (float $value): bool { + return 1.0 > $value; + }); + } + + /** + * @return \Generator + */ + public static function one(): \Generator + { + yield from self::provideDataForValuesWhere(self::values(), static function (float $value): bool { + return 1.0 === $value; + }); + } + + /** + * @return \Generator + */ + public static function greaterThanOne(): \Generator + { + yield from self::provideDataForValuesWhere(self::values(), static function (float $value): bool { + return 1.0 < $value; + }); + } + + /** + * @return array + */ + private static function values(): array + { + $faker = self::faker(); + + return [ + 'float-less-than-minus-one' => -1 * $faker->randomFloat(null, 1.01), + 'float-minus-one' => -1.0, + 'float-zero' => 0.0, + 'float-plus-one' => 1.0, + 'float-greater-than-plus-one' => $faker->randomFloat(null, 1.01), + ]; + } +} diff --git a/test/Unit/DataProvider/FloatProviderTest.php b/test/Unit/DataProvider/FloatProviderTest.php new file mode 100644 index 00000000..cc603d19 --- /dev/null +++ b/test/Unit/DataProvider/FloatProviderTest.php @@ -0,0 +1,182 @@ + Util\DataProvider\Specification\Closure::create(static function (float $value): bool { + return -1.0 > $value; + }), + 'float-minus-one' => Util\DataProvider\Specification\Identical::create(-1.0), + 'float-zero' => Util\DataProvider\Specification\Identical::create(0.0), + 'float-plus-one' => Util\DataProvider\Specification\Identical::create(1.0), + 'float-greater-than-plus-one' => Util\DataProvider\Specification\Closure::create(static function (float $value): bool { + return 1.0 < $value; + }), + ]; + + $provider = FloatProvider::arbitrary(); + + self::assertProvidesDataSetsForValuesSatisfyingSpecifications($specifications, $provider); + } + + /** + * @dataProvider \Ergebnis\Test\Util\DataProvider\FloatProvider::lessThanZero() + * + * @param float $value + */ + public function testLessThanZeroProvidesFloatLessThanZero(float $value): void + { + self::assertLessThan(0, $value); + } + + public function testLessThanZeroReturnsGeneratorThatProvidesFloatLessThanZero(): void + { + $specifications = [ + 'float-less-than-minus-one' => Util\DataProvider\Specification\Closure::create(static function (float $value): bool { + return -1.0 > $value; + }), + 'float-minus-one' => Util\DataProvider\Specification\Identical::create(-1.0), + ]; + + $provider = FloatProvider::lessThanZero(); + + self::assertProvidesDataSetsForValuesSatisfyingSpecifications($specifications, $provider); + } + + /** + * @dataProvider \Ergebnis\Test\Util\DataProvider\FloatProvider::zero() + * + * @param float $value + */ + public function testZeroProvidesZero(float $value): void + { + self::assertSame(0.0, $value); + } + + public function testZeroReturnsGeneratorThatProvidesZero(): void + { + $specifications = [ + 'float-zero' => Util\DataProvider\Specification\Identical::create(0.0), + ]; + + $provider = FloatProvider::zero(); + + self::assertProvidesDataSetsForValuesSatisfyingSpecifications($specifications, $provider); + } + + /** + * @dataProvider \Ergebnis\Test\Util\DataProvider\FloatProvider::greaterThanZero() + * + * @param float $value + */ + public function testGreaterThanZeroProvidesFloatGreaterThanZero(float $value): void + { + self::assertGreaterThan(0.0, $value); + } + + public function testGreaterThanZeroReturnsGeneratorThatProvidesFloatGreaterThanZero(): void + { + $specifications = [ + 'float-plus-one' => Util\DataProvider\Specification\Identical::create(1.0), + 'float-greater-than-plus-one' => Util\DataProvider\Specification\Closure::create(static function (float $value): bool { + return 1.0 < $value; + }), + ]; + + $provider = FloatProvider::greaterThanZero(); + + self::assertProvidesDataSetsForValuesSatisfyingSpecifications($specifications, $provider); + } + + /** + * @dataProvider \Ergebnis\Test\Util\DataProvider\FloatProvider::lessThanOne() + * + * @param float $value + */ + public function testLessThanOneProvidesFloatLessThanOne(float $value): void + { + self::assertLessThan(1, $value); + } + + public function testLessThanOneReturnsGeneratorThatProvidesFloatLessThanOne(): void + { + $specifications = [ + 'float-less-than-minus-one' => Util\DataProvider\Specification\Closure::create(static function (float $value): bool { + return -1.0 > $value; + }), + 'float-minus-one' => Util\DataProvider\Specification\Identical::create(-1.0), + 'float-zero' => Util\DataProvider\Specification\Identical::create(0.0), + ]; + + $provider = FloatProvider::lessThanOne(); + + self::assertProvidesDataSetsForValuesSatisfyingSpecifications($specifications, $provider); + } + + public function testOneReturnsGeneratorThatProvidesOne(): void + { + $specifications = [ + 'float-plus-one' => Util\DataProvider\Specification\Identical::create(1.0), + ]; + + $provider = FloatProvider::one(); + + self::assertProvidesDataSetsForValuesSatisfyingSpecifications($specifications, $provider); + } + + /** + * @dataProvider \Ergebnis\Test\Util\DataProvider\FloatProvider::greaterThanOne() + * + * @param float $value + */ + public function testGreaterThanOneProvidesFloatGreaterThanOne(float $value): void + { + self::assertGreaterThan(1, $value); + } + + public function testGreaterThanOneReturnsGeneratorThatProvidesFloatGreaterThanOne(): void + { + $specifications = [ + 'float-greater-than-plus-one' => Util\DataProvider\Specification\Closure::create(static function (float $value): bool { + return 1.0 < $value; + }), + ]; + + $provider = FloatProvider::greaterThanOne(); + + self::assertProvidesDataSetsForValuesSatisfyingSpecifications($specifications, $provider); + } +}