Skip to content

Commit

Permalink
Adds tests against PHPUnit 10.5
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro committed Jan 9, 2024
1 parent 72af784 commit afca284
Show file tree
Hide file tree
Showing 13 changed files with 727 additions and 612 deletions.
20 changes: 18 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ jobs:
fail-fast: true
matrix:
php: [8.2, 8.3]
phpunit: ['10.5', '11.0']
stability: [prefer-lowest, prefer-stable]

name: PHP ${{ matrix.php }} - ${{ matrix.stability }}
name: PHP ${{ matrix.php }} - PHPUnit ${{ matrix.phpunit }} - ${{ matrix.stability }}

steps:
- name: Checkout code
Expand All @@ -69,6 +70,13 @@ jobs:
max_attempts: 5
command: composer require guzzlehttp/psr7:^2.4 --no-interaction --no-update

- name: Set PHPUnit
uses: nick-fields/retry@v2
with:
timeout_minutes: 5
max_attempts: 5
command: composer require phpunit/phpunit:~${{ matrix.phpunit }} --dev --no-interaction --no-update

- name: Install dependencies
uses: nick-fields/retry@v2
with:
Expand Down Expand Up @@ -101,9 +109,10 @@ jobs:
fail-fast: true
matrix:
php: [8.2, 8.3]
phpunit: ['10.5', '11.0']
stability: [prefer-lowest, prefer-stable]

name: PHP ${{ matrix.php }} - ${{ matrix.stability }} - Windows
name: PHP ${{ matrix.php }} - PHPUnit ${{ matrix.phpunit }} - ${{ matrix.stability }} - Windows

steps:
- name: Set git to use LF
Expand Down Expand Up @@ -131,6 +140,13 @@ jobs:
max_attempts: 5
command: composer require guzzlehttp/psr7:~2.4 --no-interaction --no-update

- name: Set PHPUnit
uses: nick-fields/retry@v2
with:
timeout_minutes: 5
max_attempts: 5
command: composer require phpunit/phpunit:~${{ matrix.phpunit }} --dev --no-interaction --no-update

- name: Install dependencies
uses: nick-fields/retry@v2
with:
Expand Down
140 changes: 7 additions & 133 deletions src/Illuminate/Testing/Constraints/ArraySubset.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,143 +2,17 @@

namespace Illuminate\Testing\Constraints;

use ArrayObject;
use PHPUnit\Framework\Constraint\Constraint;
use SebastianBergmann\Comparator\ComparisonFailure;
use SebastianBergmann\Exporter\Exporter;
use Traversable;
use PHPUnit\Runner\Version;

/**
* @internal This class is not meant to be used or overwritten outside the framework itself.
*/
final readonly class ArraySubset extends Constraint
{
/**
* @var iterable
*/
private iterable $subset;

/**
* @var bool
*/
private bool $strict;

/**
* Create a new array subset constraint instance.
*
* @param iterable $subset
* @param bool $strict
* @return void
*/
public function __construct(iterable $subset, bool $strict = false)
if (str_starts_with(Version::series(), '10')) {
class ArraySubset extends Constraint
{
$this->strict = $strict;
$this->subset = $subset;
use Concerns\ArraySubset;
}

/**
* Evaluates the constraint for parameter $other.
*
* If $returnResult is set to false (the default), an exception is thrown
* in case of a failure. null is returned otherwise.
*
* If $returnResult is true, the result of the evaluation is returned as
* a boolean value instead: true in case of success, false in case of a
* failure.
*
* @param mixed $other
* @param string $description
* @param bool $returnResult
* @return bool|null
*
* @throws \PHPUnit\Framework\ExpectationFailedException
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
*/
public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
} else {
readonly class ArraySubset extends Constraint
{
// type cast $other & $this->subset as an array to allow
// support in standard array functions.
$other = $this->toArray($other);
$subset = $this->toArray($this->subset);

$patched = array_replace_recursive($other, $subset);

if ($this->strict) {
$result = $other === $patched;
} else {
$result = $other == $patched;
}

if ($returnResult) {
return $result;
}

if (! $result) {
$f = new ComparisonFailure(
$patched,
$other,
var_export($patched, true),
var_export($other, true)
);

$this->fail($other, $description, $f);
}

return null;
}

/**
* Returns a string representation of the constraint.
*
* @return string
*
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
*/
public function toString(): string
{
return 'has the subset '.(new Exporter)->export($this->subset);
}

/**
* Returns the description of the failure.
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other
* @return string
*
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
*/
protected function failureDescription($other): string
{
return 'an array '.$this->toString();
}

/**
* Returns the description of the failure.
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param iterable $other
* @return array
*/
private function toArray(iterable $other): array
{
if (is_array($other)) {
return $other;
}

if ($other instanceof ArrayObject) {
return $other->getArrayCopy();
}

if ($other instanceof Traversable) {
return iterator_to_array($other);
}

// Keep BC even if we know that array would not be the expected one
return (array) $other;
use Concerns\ArraySubset;
}
}
139 changes: 139 additions & 0 deletions src/Illuminate/Testing/Constraints/Concerns/ArraySubset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php

namespace Illuminate\Testing\Constraints\Concerns;

use ArrayObject;
use SebastianBergmann\Comparator\ComparisonFailure;
use SebastianBergmann\Exporter\Exporter;
use Traversable;

trait ArraySubset
{
/**
* @var iterable
*/
protected readonly iterable $subset;

/**
* @var bool
*/
protected readonly bool $strict;

/**
* Create a new array subset constraint instance.
*
* @param iterable $subset
* @param bool $strict
* @return void
*/
public function __construct(iterable $subset, bool $strict = false)
{
$this->strict = $strict;
$this->subset = $subset;
}

/**
* Evaluates the constraint for parameter $other.
*
* If $returnResult is set to false (the default), an exception is thrown
* in case of a failure. null is returned otherwise.
*
* If $returnResult is true, the result of the evaluation is returned as
* a boolean value instead: true in case of success, false in case of a
* failure.
*
* @param mixed $other
* @param string $description
* @param bool $returnResult
* @return bool|null
*
* @throws \PHPUnit\Framework\ExpectationFailedException
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
*/
public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
{
// type cast $other & $this->subset as an array to allow
// support in standard array functions.
$other = $this->toArray($other);
$subset = $this->toArray($this->subset);

$patched = array_replace_recursive($other, $subset);

if ($this->strict) {
$result = $other === $patched;
} else {
$result = $other == $patched;
}

if ($returnResult) {
return $result;
}

if (! $result) {
$f = new ComparisonFailure(
$patched,
$other,
var_export($patched, true),
var_export($other, true)
);

$this->fail($other, $description, $f);
}

return null;
}

/**
* Returns a string representation of the constraint.
*
* @return string
*
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
*/
public function toString(): string
{
return 'has the subset '.(new Exporter)->export($this->subset);
}

/**
* Returns the description of the failure.
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param mixed $other
* @return string
*
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
*/
protected function failureDescription($other): string
{
return 'an array '.$this->toString();
}

/**
* Returns the description of the failure.
*
* The beginning of failure messages is "Failed asserting that" in most
* cases. This method should return the second part of that sentence.
*
* @param iterable $other
* @return array
*/
protected function toArray(iterable $other): array
{
if (is_array($other)) {
return $other;
}

if ($other instanceof ArrayObject) {
return $other->getArrayCopy();
}

if ($other instanceof Traversable) {
return iterator_to_array($other);
}

return (array) $other;
}
}
Loading

0 comments on commit afca284

Please sign in to comment.