Skip to content

Commit

Permalink
Support non-empty-list and object collections (#53)
Browse files Browse the repository at this point in the history
* Rename NonEmptyStringProvider to NonEmptyValueProvider
Add support for non-empty-list type
- combines ListProvider with NonEmptyValueProvider to generate non-empty lists (arrays with int keys)

Add support for Collection objects using Object<A, B> syntax

* Adjust type-resolver min version to support NonEmptyList type

* Add support for hardcoded float/int/string values as typehint
  • Loading branch information
bram123 authored Aug 29, 2023
1 parent 15772d0 commit 64cc945
Show file tree
Hide file tree
Showing 26 changed files with 329 additions and 83 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"require": {
"php": ">=7.4",
"doctrine/inflector": "^2.0",
"phpdocumentor/type-resolver": "^1.6",
"phpdocumentor/type-resolver": "^1.7",
"phpunit/phpunit": "^9.0 || ^10.0"
},
"require-dev": {
Expand Down
32 changes: 32 additions & 0 deletions src/Constraint/ValueProvider/Pseudo/DirectValueProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo;

use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\ValueProvider;
use phpDocumentor\Reflection\PseudoTypes\FloatValue;
use phpDocumentor\Reflection\PseudoTypes\IntegerValue;
use phpDocumentor\Reflection\PseudoTypes\StringValue;

class DirectValueProvider implements ValueProvider
{
/** @var FloatValue|IntegerValue|StringValue */
private $valueType;

/**
* @param FloatValue|IntegerValue|StringValue $valueType
*/
public function __construct($valueType)
{
$this->valueType = $valueType;
}

/**
* @return float[]|int[]|string[]
*/
public function getValues(): array
{
return [$this->valueType->getValue()];
}
}
31 changes: 0 additions & 31 deletions src/Constraint/ValueProvider/Pseudo/NonEmptyStringProvider.php

This file was deleted.

26 changes: 26 additions & 0 deletions src/Constraint/ValueProvider/Pseudo/NonEmptyValueProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);

namespace DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo;

use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\ValueProvider;
use Exception;

class NonEmptyValueProvider implements ValueProvider
{
private ValueProvider $valueProvider;

public function __construct(ValueProvider $valueProvider)
{
$this->valueProvider = $valueProvider;
}

/**
* @return mixed[]
* @throws Exception
*/
public function getValues(): array
{
return array_filter($this->valueProvider->getValues());
}
}
17 changes: 14 additions & 3 deletions src/Constraint/ValueProvider/PseudoValueProviderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,34 @@

use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\CallableStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\ClassStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\DirectValueProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\HtmlEscapedStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\ListProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\LiteralStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\LowercaseStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NonEmptyStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NonEmptyValueProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NumericStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\TraitStringProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Scalar\FloatProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Scalar\IntProvider;
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Scalar\StringProvider;
use LogicException;
use phpDocumentor\Reflection\PseudoTypes\CallableString;
use phpDocumentor\Reflection\PseudoTypes\FloatValue;
use phpDocumentor\Reflection\PseudoTypes\HtmlEscapedString;
use phpDocumentor\Reflection\PseudoTypes\IntegerRange;
use phpDocumentor\Reflection\PseudoTypes\IntegerValue;
use phpDocumentor\Reflection\PseudoTypes\List_;
use phpDocumentor\Reflection\PseudoTypes\LiteralString;
use phpDocumentor\Reflection\PseudoTypes\LowercaseString;
use phpDocumentor\Reflection\PseudoTypes\NegativeInteger;
use phpDocumentor\Reflection\PseudoTypes\NonEmptyList;
use phpDocumentor\Reflection\PseudoTypes\NonEmptyLowercaseString;
use phpDocumentor\Reflection\PseudoTypes\NonEmptyString;
use phpDocumentor\Reflection\PseudoTypes\Numeric_;
use phpDocumentor\Reflection\PseudoTypes\NumericString;
use phpDocumentor\Reflection\PseudoTypes\PositiveInteger;
use phpDocumentor\Reflection\PseudoTypes\StringValue;
use phpDocumentor\Reflection\PseudoTypes\TraitString;
use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\Types\ArrayKey;
Expand Down Expand Up @@ -57,6 +62,8 @@ public function getProvider(Type $typehint): ?ValueProvider
return new IntProvider((int)$typehint->getMinValue(), (int)$typehint->getMaxValue());
case List_::class:
return new ListProvider($this->valueProviderFactory->getProvider($typehint->getValueType()));
case NonEmptyList::class:
return new NonEmptyValueProvider(new ListProvider($this->valueProviderFactory->getProvider($typehint->getValueType())));
case NegativeInteger::class:
return new IntProvider(PHP_INT_MIN, -1);
case Numeric_::class:
Expand Down Expand Up @@ -84,16 +91,20 @@ protected function getPseudoStringProvider(Type $typehint): ?ValueProvider
return new ClassStringProvider($fqsen);
case CallableString::class:
return new CallableStringProvider();
case FloatValue::class:
case IntegerValue::class:
case StringValue::class:
return new DirectValueProvider($typehint);
case HtmlEscapedString::class:
return new HtmlEscapedStringProvider();
case LiteralString::class:
return new LiteralStringProvider();
case LowercaseString::class:
return new LowercaseStringProvider(new StringProvider());
case NonEmptyLowercaseString::class:
return new NonEmptyStringProvider(new LowercaseStringProvider(new StringProvider()));
return new NonEmptyValueProvider(new LowercaseStringProvider(new StringProvider()));
case NonEmptyString::class:
return new NonEmptyStringProvider(new StringProvider());
return new NonEmptyValueProvider(new StringProvider());
case NumericString::class:
return new NumericStringProvider();
case TraitString::class:
Expand Down
3 changes: 2 additions & 1 deletion src/Constraint/ValueProvider/ValueProviderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Special\NullProvider;
use LogicException;
use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\Types\Collection;
use phpDocumentor\Reflection\Types\Compound;
use phpDocumentor\Reflection\Types\Intersection;
use phpDocumentor\Reflection\Types\Nullable;
Expand Down Expand Up @@ -50,7 +51,7 @@ public function getProvider(Type $typehint): ValueProvider
}

// Support for fully namespaced class name
if ($typehint instanceof Object_ && $typehint->getFqsen() !== null) {
if (($typehint instanceof Object_ || $typehint instanceof Collection) && $typehint->getFqsen() !== null) {
return new InstanceProvider((string)$typehint->getFqsen());
}

Expand Down
3 changes: 2 additions & 1 deletion tests/Integration/AccessorPairAsserterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Keyword\FalseProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\CallableStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\ClassStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\DirectValueProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\HtmlEscapedStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\ListProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\LiteralStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\LowercaseStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NonEmptyStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NonEmptyValueProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NumericStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\TraitStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Scalar\BoolProvider
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);

namespace DigitalRevolution\AccessorPairConstraint\Tests\Integration\data\success\Regular\Types\CompoundTypes;

use ArrayIterator;
use stdClass;

class CollectionProperty
{
/** @var ArrayIterator<stdClass> */
private $property = false;

/**
* @return ArrayIterator<stdClass>
*/
public function getProperty(): ArrayIterator
{
return $this->property;
}

/**
* @param ArrayIterator<stdClass> $property
*/
public function setProperty(ArrayIterator $property): self
{
$this->property = $property;

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace DigitalRevolution\AccessorPairConstraint\Tests\Integration\data\success\Regular\Types\PseudoTypes;

class FloatValueProperty
{
/** @var 1.0|2.0|3.0 */
private float $property;

/**
* @return 1.0|2.0|3.0
*/
public function getProperty(): float
{
return $this->property;
}

/**
* @param 1.0|2.0|3.0 $property
*/
public function setProperty(float $property): self
{
$this->property = $property;

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace DigitalRevolution\AccessorPairConstraint\Tests\Integration\data\success\Regular\Types\PseudoTypes;

class IntegerValueProperty
{
/** @var 1|2|3 */
private int $property;

/**
* @return 1|2|3
*/
public function getProperty(): int
{
return $this->property;
}

/**
* @param 1|2|3 $property
*/
public function setProperty(int $property): self
{
$this->property = $property;

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);

namespace DigitalRevolution\AccessorPairConstraint\Tests\Integration\data\success\Regular\Types\PseudoTypes;

class NonEmptyListProperty
{
/** @var non-empty-list */
private array $property;

/**
* @return non-empty-list
*/
public function getProperty(): array
{
return $this->property;
}

/**
* @param non-empty-list $property
*/
public function setProperty(array $property): self
{
$this->property = $property;

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace DigitalRevolution\AccessorPairConstraint\Tests\Integration\data\success\Regular\Types\PseudoTypes;

class StringValueProperty
{
/** @var 'foo'|'bar'*/
private string $property;

/**
* @return 'foo'|'bar'
*/
public function getProperty(): string
{
return $this->property;
}

/**
* @param 'foo'|'bar' $property
*/
public function setProperty(string $property): self
{
$this->property = $property;

return $this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\ListProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\LiteralStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\LowercaseStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NonEmptyStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NonEmptyValueProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\NumericStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\TraitStringProvider
* @uses \DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Scalar\BoolProvider
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
declare(strict_types=1);

namespace Constraint\ValueProvider\Pseudo;
namespace DigitalRevolution\AccessorPairConstraint\Tests\Unit\Constraint\ValueProvider\Pseudo;

use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\CallableStringProvider;
use DigitalRevolution\AccessorPairConstraint\Tests\Unit\Constraint\ValueProvider\AbstractValueProviderTestCase;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
declare(strict_types=1);

namespace Constraint\ValueProvider\Pseudo;
namespace DigitalRevolution\AccessorPairConstraint\Tests\Unit\Constraint\ValueProvider\Pseudo;

use DigitalRevolution\AccessorPairConstraint\Constraint\ValueProvider\Pseudo\ClassStringProvider;
use DigitalRevolution\AccessorPairConstraint\Tests\Unit\Constraint\ValueProvider\AbstractValueProviderTestCase;
Expand Down
Loading

0 comments on commit 64cc945

Please sign in to comment.