From 98e977b8e2527d7805f6deb0f3c1f36c07e6872d Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 10 May 2026 15:46:13 +0200 Subject: [PATCH 1/4] move MadeOf to Provider namespace --- CHANGELOG.md | 1 + src/Set/Provider/Strings.php | 4 ++-- src/Set/{ => Provider/Strings}/MadeOf.php | 5 ++++- src/Set/Provider/Strings/Unicode.php | 1 - 4 files changed, 7 insertions(+), 4 deletions(-) rename src/Set/{ => Provider/Strings}/MadeOf.php (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index c64f9cb..86e1bab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ - PHPUnit attributes `Group` and `DataProvider` are now longer read when running tests with BlackBox, use the `Innmind\BlackBox\` prefixed ones instead - All proofs will fail if they throw an exception (instead of stopping the script) - `Innmind\BlackBox\Runner\Printer` is now a final class +- `Innmind\BlackBox\Set\MadeOf` have been moved to `Innmind\BlackBox\Set\Provider\Strings\MadeOf` ### Removed diff --git a/src/Set/Provider/Strings.php b/src/Set/Provider/Strings.php index 5223394..4c24445 100644 --- a/src/Set/Provider/Strings.php +++ b/src/Set/Provider/Strings.php @@ -75,9 +75,9 @@ public function unsafe(): Set * @param Set|Provider $rest */ #[\NoDiscard] - public function madeOf(Set|Provider $first, Set|Provider ...$rest): Set\MadeOf + public function madeOf(Set|Provider $first, Set|Provider ...$rest): Strings\MadeOf { - return Set\MadeOf::of($first, ...$rest); + return Strings\MadeOf::of($first, ...$rest); } /** diff --git a/src/Set/MadeOf.php b/src/Set/Provider/Strings/MadeOf.php similarity index 97% rename from src/Set/MadeOf.php rename to src/Set/Provider/Strings/MadeOf.php index 08a2a0a..a3c51aa 100644 --- a/src/Set/MadeOf.php +++ b/src/Set/Provider/Strings/MadeOf.php @@ -1,10 +1,12 @@ Date: Sun, 10 May 2026 15:57:09 +0200 Subject: [PATCH 2/4] move Properties to Provider namespace --- CHANGELOG.md | 2 ++ fixtures/proofs.php | 2 +- proofs/application.php | 2 +- src/Set.php | 14 ++++++++++++++ src/Set/{ => Provider}/Properties.php | 5 ++++- tests/Set/PropertiesTest.php | 19 +++++++++---------- 6 files changed, 31 insertions(+), 13 deletions(-) rename src/Set/{ => Provider}/Properties.php (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86e1bab..af8bee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - `Innmind\BlackBox\Set::disableShrinking()` - `Innmind\BlackBox\Set::toSet()` - `Innmind\BlackBox\Set::zip()` +- `Innmind\BlackBox\Set::properties()` - `Innmind\BlackBox\Runner\Proof::tagged()` - `Innmind\BlackBox\Runner\Proof::disableShrinking()` - `Innmind\BlackBox\Application::mapProof()` @@ -28,6 +29,7 @@ - All proofs will fail if they throw an exception (instead of stopping the script) - `Innmind\BlackBox\Runner\Printer` is now a final class - `Innmind\BlackBox\Set\MadeOf` have been moved to `Innmind\BlackBox\Set\Provider\Strings\MadeOf` +- `Innmind\BlackBox\Set\Properties` have been moved to `Innmind\BlackBox\Set\Provider\Properties` ### Removed diff --git a/fixtures/proofs.php b/fixtures/proofs.php index 51846b1..0980215 100644 --- a/fixtures/proofs.php +++ b/fixtures/proofs.php @@ -84,7 +84,7 @@ yield $prove ->properties( 'Counter properties', - Set\Properties::any( + Set::properties( DownAndUpIsAnIdentityFunction::any(), DownChangeState::any(), LowerBoundAtZero::any(), diff --git a/proofs/application.php b/proofs/application.php index 23deeae..32632e3 100644 --- a/proofs/application.php +++ b/proofs/application.php @@ -93,7 +93,7 @@ ->tryToProve(static function($prove) { yield $prove->properties( 'Counter properties', - Set\Properties::any( + Set::properties( DownAndUpIsAnIdentityFunction::any(), DownChangeState::any(), LowerBoundAtZero::any(), diff --git a/src/Set.php b/src/Set.php index bf5d81c..35de40c 100644 --- a/src/Set.php +++ b/src/Set.php @@ -201,6 +201,20 @@ public static function strings(): Provider\Strings return Provider\Strings::of(self::build(...)); } + /** + * @psalm-pure + * + * @no-named-arguments + * + * @param self|Provider $first + * @param self|Provider $properties + */ + #[\NoDiscard] + public static function properties(self|Provider $first, self|Provider ...$properties): Provider\Properties + { + return Provider\Properties::any($first, ...$properties); + } + /** * @psalm-pure * diff --git a/src/Set/Properties.php b/src/Set/Provider/Properties.php similarity index 97% rename from src/Set/Properties.php rename to src/Set/Provider/Properties.php index 3c5ba30..28d8c36 100644 --- a/src/Set/Properties.php +++ b/src/Set/Provider/Properties.php @@ -1,10 +1,12 @@ assertInstanceOf( Set\Provider::class, - Properties::any( + Set::properties( Set::of(new LowerBoundAtZero), ), ); @@ -28,7 +27,7 @@ public function testInterface() public function testGenerate100ScenariiByDefault() { - $properties = Properties::any( + $properties = Set::properties( Set::of(new LowerBoundAtZero), ); @@ -45,18 +44,18 @@ public function testGenerate100ScenariiByDefault() public function testGeneratePropertiesModel() { - $properties = Properties::any( + $properties = Set::properties( Set::of(new LowerBoundAtZero), ); foreach ($properties->toSet()->take(100)->values(Random::mersenneTwister) as $scenario) { - $this->assertInstanceOf(PropertiesModel::class, $scenario->unwrap()); + $this->assertInstanceOf(Properties::class, $scenario->unwrap()); } } public function testScenariiAreOfDifferentSizes() { - $properties = Properties::any( + $properties = Set::properties( Set::of(new LowerBoundAtZero), ); $sizes = []; @@ -70,7 +69,7 @@ public function testScenariiAreOfDifferentSizes() public function testTake() { - $properties = Properties::any( + $properties = Set::properties( Set::of(new LowerBoundAtZero), )->take(100); $properties2 = $properties->take(50); @@ -83,7 +82,7 @@ public function testTake() public function testFilter() { - $properties = Properties::any( + $properties = Set::properties( Set::of(new LowerBoundAtZero), ); $properties2 = $properties->filter(static fn($scenario) => \count($scenario->properties()) > 50); @@ -111,7 +110,7 @@ public function testFilter() public function testMaxNumberOfPropertiesGeneratedAtOnce() { - $properties = Properties::any( + $properties = Set::properties( Set::of(new LowerBoundAtZero), )->atMost(50); $sizes = []; From a2fc812ae60f83bd9f98183f973d2c3f603df4a6 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 10 May 2026 16:02:16 +0200 Subject: [PATCH 3/4] move Slice to Provider namespace --- CHANGELOG.md | 2 ++ proofs/set/slice.php | 8 ++++---- src/Set.php | 9 +++++++++ src/Set/{ => Provider}/Slice.php | 14 ++++++++++---- 4 files changed, 25 insertions(+), 8 deletions(-) rename src/Set/{ => Provider}/Slice.php (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index af8bee7..67b7152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - `Innmind\BlackBox\Set::toSet()` - `Innmind\BlackBox\Set::zip()` - `Innmind\BlackBox\Set::properties()` +- `Innmind\BlackBox\Set::slice()` - `Innmind\BlackBox\Runner\Proof::tagged()` - `Innmind\BlackBox\Runner\Proof::disableShrinking()` - `Innmind\BlackBox\Application::mapProof()` @@ -30,6 +31,7 @@ - `Innmind\BlackBox\Runner\Printer` is now a final class - `Innmind\BlackBox\Set\MadeOf` have been moved to `Innmind\BlackBox\Set\Provider\Strings\MadeOf` - `Innmind\BlackBox\Set\Properties` have been moved to `Innmind\BlackBox\Set\Provider\Properties` +- `Innmind\BlackBox\Set\Slice` have been moved to `Innmind\BlackBox\Set\Provider\Slice` ### Removed diff --git a/proofs/set/slice.php b/proofs/set/slice.php index 2a19d79..7dbca3b 100644 --- a/proofs/set/slice.php +++ b/proofs/set/slice.php @@ -8,10 +8,10 @@ return static function($prove) { yield $prove - ->proof('Set\Slice') + ->proof('Set::slice()') ->given( Set::sequence(Set::type())->atLeast(11), - Set\Slice::between(10, 20), + Set::slice()->between(10, 20), ) ->test(static function($assert, $values, $slice) { $subset = $slice($values); @@ -31,10 +31,10 @@ ->tag(Tag::ci, Tag::local); yield $prove - ->proof('Set\Slice min length') + ->proof('Set::slice() min length') ->given( Set::sequence(Set::type())->atLeast(2), - Set\Slice::any()->atLeast(2), + Set::slice()->atLeast(2), ) ->test(static function($assert, $values, $slice) { $subset = $slice($values); diff --git a/src/Set.php b/src/Set.php index 35de40c..b76d435 100644 --- a/src/Set.php +++ b/src/Set.php @@ -215,6 +215,15 @@ public static function properties(self|Provider $first, self|Provider ...$proper return Provider\Properties::any($first, ...$properties); } + /** + * @psalm-pure + */ + #[\NoDiscard] + public static function slice(): Provider\Slice + { + return Provider\Slice::any(); + } + /** * @psalm-pure * diff --git a/src/Set/Slice.php b/src/Set/Provider/Slice.php similarity index 93% rename from src/Set/Slice.php rename to src/Set/Provider/Slice.php index 380a4ea..0052b3a 100644 --- a/src/Set/Slice.php +++ b/src/Set/Provider/Slice.php @@ -1,10 +1,12 @@ $min * @param int<0, max> $max */ #[\NoDiscard] - public static function between(int $min, int $max): self + public function between(int $min, int $max): self { - return new self($min, $max, 0); + return new self( + $min, + $max, + $this->atLeast, + ); } /** From c523c6d49f742cb284ea52010687931cb2a2ad9c Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 10 May 2026 16:05:15 +0200 Subject: [PATCH 4/4] move MutuallyExclusive to a method on Strings provider --- CHANGELOG.md | 2 ++ proofs/set/mutuallyExclusive.php | 4 +-- src/Set/MutuallyExclusive.php | 47 -------------------------------- src/Set/Provider/Strings.php | 38 ++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 49 deletions(-) delete mode 100644 src/Set/MutuallyExclusive.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 67b7152..7f51d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `Innmind\BlackBox\Set::zip()` - `Innmind\BlackBox\Set::properties()` - `Innmind\BlackBox\Set::slice()` +- `Innmind\BlackBox\Set\Provider\Strings::mutuallyExclusive()` - `Innmind\BlackBox\Runner\Proof::tagged()` - `Innmind\BlackBox\Runner\Proof::disableShrinking()` - `Innmind\BlackBox\Application::mapProof()` @@ -84,6 +85,7 @@ - `Innmind\BlackBox\Set\Tuple` - `Innmind\BlackBox\Set\Type` - `Innmind\BlackBox\Set\Unicode` +- `Innmind\BlackBox\Set\MutuallyExclusive` - `Innmind\BlackBox\Set\UnsafeStrings::any()` - `Innmind\BlackBox\Set\Uuid` - `Innmind\BlackBox\Set::decorate()` diff --git a/proofs/set/mutuallyExclusive.php b/proofs/set/mutuallyExclusive.php index d98e005..5b5f823 100644 --- a/proofs/set/mutuallyExclusive.php +++ b/proofs/set/mutuallyExclusive.php @@ -8,8 +8,8 @@ return static function($prove) { yield $prove - ->proof('Set\MutuallyExclusive') - ->given(Set\MutuallyExclusive::of( + ->proof('Set::strings()->mutuallyExclusive()') + ->given(Set::strings()->mutuallyExclusive( Set::strings()->madeOf(Set::strings()->unicode()->char(), Set::strings()->chars()), Set::strings()->madeOf(Set::strings()->unicode()->char(), Set::strings()->chars()), Set::strings()->madeOf(Set::strings()->unicode()->char(), Set::strings()->chars()), diff --git a/src/Set/MutuallyExclusive.php b/src/Set/MutuallyExclusive.php deleted file mode 100644 index 255fcea..0000000 --- a/src/Set/MutuallyExclusive.php +++ /dev/null @@ -1,47 +0,0 @@ -|Provider $first - * @param Set|Provider $second - * @param Set|Provider $rest - * - * @return Set> - */ - #[\NoDiscard] - public static function of( - Set|Provider $first, - Set|Provider $second, - Set|Provider ...$rest, - ): Set { - /** @var Set> */ - return Set::tuple( - $first, - $second, - ...$rest, - )->filter(static function($strings) { - foreach ($strings as $i => $a) { - foreach ($strings as $j => $b) { - if ($i === $j) { - continue; - } - - if (\str_contains(\strtolower($a), \strtolower($b))) { - return false; - } - } - } - - return true; - }); - } -} diff --git a/src/Set/Provider/Strings.php b/src/Set/Provider/Strings.php index 4c24445..dd1a242 100644 --- a/src/Set/Provider/Strings.php +++ b/src/Set/Provider/Strings.php @@ -80,6 +80,44 @@ public function madeOf(Set|Provider $first, Set|Provider ...$rest): Strings\Made return Strings\MadeOf::of($first, ...$rest); } + /** + * @psalm-pure + * @no-named-arguments + * + * @param Set|Provider $first + * @param Set|Provider $second + * @param Set|Provider $rest + * + * @return Set> + */ + #[\NoDiscard] + public function mutuallyExclusive( + Set|Provider $first, + Set|Provider $second, + Set|Provider ...$rest, + ): Set { + /** @var Set> */ + return Set::tuple( + $first, + $second, + ...$rest, + )->filter(static function($strings) { + foreach ($strings as $i => $a) { + foreach ($strings as $j => $b) { + if ($i === $j) { + continue; + } + + if (\str_contains(\strtolower($a), \strtolower($b))) { + return false; + } + } + } + + return true; + }); + } + /** * @psalm-mutation-free *