Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  remove psalm errors
  add unicode set
  push filtering to the underlying set to increase ability to generate valid values
  allow to specify the range of properties to generate
  publicly expose Properties::chooseFrom()
  fix psalm errors
  Fix a typo in the README
  • Loading branch information
Baptouuuu committed May 17, 2020
2 parents 33fe93b + c9a5fc5 commit 1105e9d
Show file tree
Hide file tree
Showing 9 changed files with 2,374 additions and 56 deletions.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -15,6 +15,7 @@ The goal of this library is to help build higher order sets to facilitate the un
`BlackBox` comes with the `Set`s of primitives:
- [`Integers`](src/Set/Integers.php) -> `int`
- [`RealNumbers`](src/Set/RealNumbers.php) -> `float`
- [`Unicode`](src/Set/Unicode.php) -> `string`
- [`Strings`](src/Set/Strings.php) -> `string`
- [`UnsafeStrings`](src/Set/UnsafeStrings.php) -> `string` (found [here](https://github.com/minimaxir/big-list-of-naughty-strings))
- [`Regex`](src/Set/Regex.php) -> `string`
Expand Down Expand Up @@ -160,7 +161,7 @@ class CounterTest extends \PHPUnit\Framework\TestCase
Set\Integers::between(0, 100), // counter bounds
)
->then(function($scenario, $initial) {
$scenario->ensureHelBy(new Counter($initial));
$scenario->ensureHeldBy(new Counter($initial));
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/PHPUnit/Scenario.php
Expand Up @@ -35,14 +35,14 @@ public function __construct(
if (\count($sets) === 0) {
/** @var Set<array<mixed>> */
$set = Set\Decorate::immutable(
/** @psalm-suppress MissingParamType */
/** @psalm-suppress MissingClosureParamType */
static fn($value): array => [$value],
$first,
);
} else {
/** @var Set<array<mixed>> */
$set = Set\Composite::immutable(
/** @psalm-suppress MissingParamType */
/** @psalm-suppress MissingClosureParamType */
static fn(...$args): array => $args,
$first,
...$sets,
Expand Down
55 changes: 8 additions & 47 deletions src/Set/Decorate.php
Expand Up @@ -19,8 +19,6 @@ final class Decorate implements Set
private \Closure $decorate;
/** @var Set<I> */
private Set $set;
/** @var \Closure(D): bool */
private \Closure $predicate;
private bool $immutable;

/**
Expand All @@ -33,7 +31,6 @@ private function __construct(bool $immutable, callable $decorate, Set $set)
$this->decorate = \Closure::fromCallable($decorate);
$this->set = $set;
$this->immutable = $immutable;
$this->predicate = static fn(): bool => true;
}

/**
Expand Down Expand Up @@ -74,34 +71,23 @@ public function take(int $size): Set

public function filter(callable $predicate): Set
{
$previous = $this->predicate;
$self = clone $this;
/** @psalm-suppress MissingClosureParamType */
$self->predicate = static function($value) use ($previous, $predicate): bool {
/** @var D */
$value = $value;

if (!$previous($value)) {
return false;
}

return $predicate($value);
};
/**
* @psalm-suppress MissingClosureParamType
* @psalm-suppress MixedArgument
*/
$self->set = $this->set->filter(fn($value): bool => $predicate(($this->decorate)($value)));

return $self;
}

public function values(Random $rand): \Generator
{
foreach ($this->set->values($rand) as $value) {
/** @var D */
$decorated = ($this->decorate)($value->unwrap());

if (!($this->predicate)($decorated)) {
continue;
}

if ($value->isImmutable() && $this->immutable) {
/** @var D */
$decorated = ($this->decorate)($value->unwrap());

yield Value::immutable(
$decorated,
$this->shrink(false, $value),
Expand Down Expand Up @@ -147,12 +133,6 @@ private function shrink(bool $mutable, Value $value): ?Dichotomy
*/
private function shrinkWithStrategy(bool $mutable, Value $value, Value $strategy): callable
{
$shrinked = ($this->decorate)($strategy->unwrap());

if (!($this->predicate)($shrinked)) {
return $this->identity($mutable, $value);
}

if ($mutable) {
/** @psalm-suppress MissingClosureReturnType */
return fn(): Value => Value::mutable(
Expand All @@ -166,23 +146,4 @@ private function shrinkWithStrategy(bool $mutable, Value $value, Value $strategy
$this->shrink(false, $strategy),
);
}

/**
* @param Value<I> $value
*
* @return callable(): Value<D>
*/
private function identity(bool $mutable, Value $value): callable
{
if ($mutable) {
/** @psalm-suppress MissingClosureReturnType */
return fn(): Value => Value::mutable(
fn() => ($this->decorate)($value->unwrap()),
);
}

return fn(): Value => Value::immutable(
($this->decorate)($value->unwrap()),
);
}
}
15 changes: 10 additions & 5 deletions src/Set/Properties.php
Expand Up @@ -39,15 +39,20 @@ public static function any(Set $first, Set ...$properties): Set
}

/**
* @param Set<Concrete> $set
*
* @return Set<Ensure>
*/
private static function chooseFrom(Set $set): Set
public static function chooseFrom(Set $set, Integers $range = null): Set
{
$range ??= Integers::between(1, 100);

if ($range->lowerBound() < 1) {
throw new \LogicException('At least one property is required');
}

/** @var Set<list<Concrete>> */
$sequences = Sequence::of(
$set,
Integers::between(1, 100), // at least one property must be chosen
);
$sequences = Sequence::of($set, $range);

/** @psalm-suppress MixedArgument */
return Decorate::immutable(
Expand Down
2 changes: 1 addition & 1 deletion src/Set/Property.php
Expand Up @@ -24,7 +24,7 @@ public static function of(string $property, Set ...$inputs): Set
}

if ($count === 1) {
/** @psalm-suppress MissingParamType */
/** @psalm-suppress MissingClosureParamType */
return Decorate::immutable(
static fn($input): Concrete => new $property($input),
\reset($inputs),
Expand Down

0 comments on commit 1105e9d

Please sign in to comment.