Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.4] Support amount 0 in Arr::random() #20439

Merged
merged 9 commits into from
Aug 6, 2017
14 changes: 11 additions & 3 deletions src/Illuminate/Support/Arr.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ public static function pull(&$array, $key, $default = null)
}

/**
* Get a random value from an array.
* Get one or a specified number of random values from an array.
*
* @param array $array
* @param int|null $amount
Expand All @@ -464,16 +464,24 @@ public static function pull(&$array, $key, $default = null)
*/
public static function random($array, $amount = null)
{
if (($requested = $amount ?: 1) > ($count = count($array))) {
$requested = is_null($amount) ? 1 : $amount;

$count = count($array);

if ($requested > $count) {
throw new InvalidArgumentException(
"You requested {$requested} items, but there are only {$count} items in the array."
"You requested {$requested} items, but there are only {$count} items available."
);
}

if (is_null($amount)) {
return $array[array_rand($array)];
}

if ((int) $amount === 0) {
return [];
}

$keys = array_rand($array, $amount);

$results = [];
Expand Down
13 changes: 1 addition & 12 deletions src/Illuminate/Support/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use CachingIterator;
use JsonSerializable;
use IteratorAggregate;
use InvalidArgumentException;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Contracts\Support\Arrayable;
Expand Down Expand Up @@ -1070,7 +1069,7 @@ public function put($key, $value)
}

/**
* Get zero or more items randomly from the collection.
* Get one or a specified number of items randomly from the collection.
*
* @param int|null $amount
* @return mixed
Expand All @@ -1079,16 +1078,6 @@ public function put($key, $value)
*/
public function random($amount = null)
{
if ($amount === 0) {
return new static;
}

if (($requested = $amount ?: 1) > ($count = $this->count())) {
throw new InvalidArgumentException(
"You requested {$requested} items, but there are only {$count} items in the collection."
);
}

if (is_null($amount)) {
return Arr::random($this->items);
}
Expand Down
78 changes: 65 additions & 13 deletions tests/Support/SupportArrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -421,22 +421,74 @@ public function testPull()

public function testRandom()
{
$randomValue = Arr::random(['foo', 'bar', 'baz']);

$this->assertContains($randomValue, ['foo', 'bar', 'baz']);

$randomValues = Arr::random(['foo', 'bar', 'baz'], 1);
$random = Arr::random(['foo', 'bar', 'baz']);
$this->assertContains($random, ['foo', 'bar', 'baz']);

$random = Arr::random(['foo', 'bar', 'baz'], 0);
$this->assertInternalType('array', $random);
$this->assertCount(0, $random);

$random = Arr::random(['foo', 'bar', 'baz'], 1);
$this->assertInternalType('array', $random);
$this->assertCount(1, $random);
$this->assertContains($random[0], ['foo', 'bar', 'baz']);

$random = Arr::random(['foo', 'bar', 'baz'], 2);
$this->assertInternalType('array', $random);
$this->assertCount(2, $random);
$this->assertContains($random[0], ['foo', 'bar', 'baz']);
$this->assertContains($random[1], ['foo', 'bar', 'baz']);

$random = Arr::random(['foo', 'bar', 'baz'], '0');
$this->assertInternalType('array', $random);
$this->assertCount(0, $random);

$random = Arr::random(['foo', 'bar', 'baz'], '1');
$this->assertInternalType('array', $random);
$this->assertCount(1, $random);
$this->assertContains($random[0], ['foo', 'bar', 'baz']);

$random = Arr::random(['foo', 'bar', 'baz'], '2');
$this->assertInternalType('array', $random);
$this->assertCount(2, $random);
$this->assertContains($random[0], ['foo', 'bar', 'baz']);
$this->assertContains($random[1], ['foo', 'bar', 'baz']);
}

$this->assertInternalType('array', $randomValues);
$this->assertCount(1, $randomValues);
$this->assertContains($randomValues[0], ['foo', 'bar', 'baz']);
public function testRandomOnEmptyArray()
{
$random = Arr::random([], 0);
$this->assertInternalType('array', $random);
$this->assertCount(0, $random);

$randomValues = Arr::random(['foo', 'bar', 'baz'], 2);
$random = Arr::random([], '0');
$this->assertInternalType('array', $random);
$this->assertCount(0, $random);
}

$this->assertInternalType('array', $randomValues);
$this->assertCount(2, $randomValues);
$this->assertContains($randomValues[0], ['foo', 'bar', 'baz']);
$this->assertContains($randomValues[1], ['foo', 'bar', 'baz']);
public function testRandomThrowsAnErrorWhenRequestingMoreItemsThanAreAvailable()
{
$exceptions = 0;

try {
Arr::random([]);
} catch (\InvalidArgumentException $e) {
++$exceptions;
}

try {
Arr::random([], 1);
} catch (\InvalidArgumentException $e) {
++$exceptions;
}

try {
Arr::random([], 2);
} catch (\InvalidArgumentException $e) {
++$exceptions;
}

$this->assertSame(3, $exceptions);
}

public function testSet()
Expand Down
57 changes: 43 additions & 14 deletions tests/Support/SupportCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,10 @@ public function testRandom()
{
$data = new Collection([1, 2, 3, 4, 5, 6]);

$random = $data->random();
$this->assertInternalType('integer', $random);
$this->assertContains($random, $data->all());

$random = $data->random(0);
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(0, $random);
Expand All @@ -919,9 +923,21 @@ public function testRandom()
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(1, $random);

$random = $data->random(3);
$random = $data->random(2);
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(2, $random);

$random = $data->random('0');
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(0, $random);

$random = $data->random('1');
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(1, $random);

$random = $data->random('2');
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(3, $random);
$this->assertCount(2, $random);
}

public function testRandomOnEmptyCollection()
Expand All @@ -931,23 +947,36 @@ public function testRandomOnEmptyCollection()
$random = $data->random(0);
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(0, $random);
}

public function testRandomWithoutArgument()
{
$data = new Collection([1, 2, 3, 4, 5, 6]);

$random = $data->random();
$this->assertInternalType('integer', $random);
$this->assertContains($random, $data->all());
$random = $data->random('0');
$this->assertInstanceOf(Collection::class, $random);
$this->assertCount(0, $random);
}

/**
* @expectedException InvalidArgumentException
*/
public function testRandomThrowsAnErrorWhenRequestingMoreItemsThanAreAvailable()
{
(new Collection)->random();
$data = new Collection();
$exceptions = 0;

try {
$data->random();
} catch (\InvalidArgumentException $e) {
++$exceptions;
}

try {
$data->random(1);
} catch (\InvalidArgumentException $e) {
++$exceptions;
}

try {
$data->random(2);
} catch (\InvalidArgumentException $e) {
++$exceptions;
}

$this->assertSame(3, $exceptions);
}

public function testTakeLast()
Expand Down