Skip to content

Commit

Permalink
allows passing an enum to randomElement() or randomElements() (#…
Browse files Browse the repository at this point in the history
…620)

* allows passing an enum to randomElement or randomElements

* psalm fix

* fix: array not an instanceof Traversable

* specify class-string

* Update test/Faker/Provider/BaseTest.php

Co-authored-by: Andreas Möller <am@localheinz.com>

* remove require_once

Co-authored-by: Andreas Möller <am@localheinz.com>

* clean up tests

splits tests, splits phases of tests, adds more specific assertions

Co-authored-by: Andreas Möller <am@localheinz.com>

* Apply suggestions from code review

Co-authored-by: Andreas Möller <am@localheinz.com>

* Fix: Avoid unnecessary import

* Fix: Remove unnecessary reference to root namespace

* Fix: Exclude BackedEnum

* Fix: DocBlock

* Fix: Run 'make baseline'

* Fix: Run 'make baseline'

* Fix: Test

---------

Co-authored-by: Andreas Möller <am@localheinz.com>
  • Loading branch information
cosmastech and localheinz authored May 14, 2023
1 parent cd773f4 commit 096f7ff
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
'.github/',
'vendor-bin/',
])
->notPath([
'test/Fixture/Enum/BackedEnum.php',
])
->ignoreDotFiles(false)
->in(__DIR__);

Expand Down
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,11 @@ parameters:
count: 1
path: src/Faker/ORM/Spot/Populator.php

-
message: "#^Class UnitEnum not found\\.$#"
count: 2
path: src/Faker/Provider/Base.php

-
message: """
#^Instantiation of deprecated class Faker\\\\DefaultGenerator\\:
Expand Down
8 changes: 8 additions & 0 deletions psalm.baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,17 @@
<InvalidArgument>
<code>[static::class, 'randomDigit']</code>
</InvalidArgument>
<UndefinedClass>
<code>\UnitEnum</code>
<code>\UnitEnum</code>
</UndefinedClass>
<UndefinedDocblockClass>
<code>Closure</code>
</UndefinedDocblockClass>
<UndefinedFunction>
<code>enum_exists($array)</code>
<code>enum_exists($array)</code>
</UndefinedFunction>
</file>
<file src="src/Faker/Provider/Biased.php">
<InvalidParamDefault>
Expand Down
22 changes: 16 additions & 6 deletions src/Faker/Provider/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ public static function randomAscii()
/**
* Returns randomly ordered subsequence of $count elements from a provided array
*
* @param array|\Traversable $array Array to take elements from. Defaults to a-c
* @param int $count Number of elements to take.
* @param bool $allowDuplicates Allow elements to be picked several times. Defaults to false
* @param array|class-string|\Traversable $array Array to take elements from. Defaults to a-c
* @param int $count Number of elements to take.
* @param bool $allowDuplicates Allow elements to be picked several times. Defaults to false
*
* @throws \InvalidArgumentException
* @throws \LengthException When requesting more elements than provided
Expand All @@ -192,13 +192,18 @@ public static function randomElements($array = ['a', 'b', 'c'], $count = 1, $all
{
$elements = $array;

if (is_string($array) && function_exists('enum_exists') && enum_exists($array)) {
$elements = $array::cases();
}

if ($array instanceof \Traversable) {
$elements = \iterator_to_array($array, false);
}

if (!is_array($elements)) {
throw new \InvalidArgumentException(sprintf(
'Argument for parameter $array needs to be array or an instance of %s, got %s instead.',
'Argument for parameter $array needs to be array, an instance of %s, or an instance of %s, got %s instead.',
\UnitEnum::class,
\Traversable::class,
is_object($array) ? get_class($array) : gettype($array),
));
Expand Down Expand Up @@ -245,14 +250,18 @@ public static function randomElements($array = ['a', 'b', 'c'], $count = 1, $all
/**
* Returns a random element from a passed array
*
* @param array|\Traversable $array
* @param array|class-string|\Traversable $array
*
* @throws \InvalidArgumentException
*/
public static function randomElement($array = ['a', 'b', 'c'])
{
$elements = $array;

if (is_string($array) && function_exists('enum_exists') && enum_exists($array)) {
$elements = $array::cases();
}

if ($array instanceof \Traversable) {
$elements = iterator_to_array($array, false);
}
Expand All @@ -263,7 +272,8 @@ public static function randomElement($array = ['a', 'b', 'c'])

if (!is_array($elements)) {
throw new \InvalidArgumentException(sprintf(
'Argument for parameter $array needs to be array or an instance of %s, got %s instead.',
'Argument for parameter $array needs to be array, an instance of %s, or an instance of %s, got %s instead.',
\UnitEnum::class,
\Traversable::class,
is_object($array) ? get_class($array) : gettype($array),
));
Expand Down
30 changes: 28 additions & 2 deletions test/Faker/Provider/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Faker\Test\Provider;

use Faker\Provider\Base as BaseProvider;
use Faker\Test\Fixture;
use Faker\Test\TestCase;

/**
Expand Down Expand Up @@ -552,7 +553,8 @@ public function testRandomElementsRejectsInvalidArgument(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(sprintf(
'Argument for parameter $array needs to be array or an instance of %s, got %s instead.',
'Argument for parameter $array needs to be array, an instance of %s, or an instance of %s, got %s instead.',
\UnitEnum::class,
\Traversable::class,
\stdClass::class,
));
Expand All @@ -564,7 +566,8 @@ public function testRandomElementRejectsInvalidArgument(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(sprintf(
'Argument for parameter $array needs to be array or an instance of %s, got %s instead.',
'Argument for parameter $array needs to be array, an instance of %s, or an instance of %s, got %s instead.',
\UnitEnum::class,
\Traversable::class,
'string',
));
Expand Down Expand Up @@ -609,6 +612,29 @@ public function testRandomElementsWorksWithAllowDuplicates(): void
self::assertCount(3, $randomElements);
self::assertContainsOnly('string', $randomElements);
}

/**
* @requires PHP 8.1
*/
public function testRandomElementsWithEnum(): void
{
$count = 2;

$randomElements = BaseProvider::randomElements(Fixture\Enum\BackedEnum::class, $count);

self::assertCount($count, $randomElements);
self::assertContainsOnlyInstancesOf(Fixture\Enum\BackedEnum::class, $randomElements);
}

/**
* @requires PHP 8.1
*/
public function testRandomElementWithEnum(): void
{
$randomElement = BaseProvider::randomElement(Fixture\Enum\BackedEnum::class);

self::assertInstanceOf(Fixture\Enum\BackedEnum::class, $randomElement);
}
}

/**
Expand Down
12 changes: 12 additions & 0 deletions test/Fixture/Enum/BackedEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Faker\Test\Fixture\Enum;

enum BackedEnum: string
{
case Assigned = 'assigned';

case Pending = 'unassigned';

case Deleted = 'removed';
}

0 comments on commit 096f7ff

Please sign in to comment.