From afca284af864ad7761e4608341d75ed176aaa70b Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 9 Jan 2024 16:23:27 +0000 Subject: [PATCH] Adds tests against PHPUnit 10.5 --- .github/workflows/tests.yml | 20 ++- .../Testing/Constraints/ArraySubset.php | 140 +----------------- .../Constraints/Concerns/ArraySubset.php | 139 +++++++++++++++++ .../Constraints/Concerns/CountInDatabase.php | 82 ++++++++++ .../Constraints/Concerns/HasInDatabase.php | 122 +++++++++++++++ .../Concerns/NotSoftDeletedInDatabase.php | 119 +++++++++++++++ .../Constraints/Concerns/SeeInOrder.php | 87 +++++++++++ .../Concerns/SoftDeletedInDatabase.php | 118 +++++++++++++++ .../Testing/Constraints/CountInDatabase.php | 79 +--------- .../Testing/Constraints/HasInDatabase.php | 119 +-------------- .../Constraints/NotSoftDeletedInDatabase.php | 115 +------------- .../Testing/Constraints/SeeInOrder.php | 84 +---------- .../Constraints/SoftDeletedInDatabase.php | 115 +------------- 13 files changed, 727 insertions(+), 612 deletions(-) create mode 100644 src/Illuminate/Testing/Constraints/Concerns/ArraySubset.php create mode 100644 src/Illuminate/Testing/Constraints/Concerns/CountInDatabase.php create mode 100644 src/Illuminate/Testing/Constraints/Concerns/HasInDatabase.php create mode 100644 src/Illuminate/Testing/Constraints/Concerns/NotSoftDeletedInDatabase.php create mode 100644 src/Illuminate/Testing/Constraints/Concerns/SeeInOrder.php create mode 100644 src/Illuminate/Testing/Constraints/Concerns/SoftDeletedInDatabase.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 292e06fd86d3..9512bc55bcfe 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -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 @@ -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: @@ -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 @@ -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: diff --git a/src/Illuminate/Testing/Constraints/ArraySubset.php b/src/Illuminate/Testing/Constraints/ArraySubset.php index 09113ed62d18..7d745c078d9b 100644 --- a/src/Illuminate/Testing/Constraints/ArraySubset.php +++ b/src/Illuminate/Testing/Constraints/ArraySubset.php @@ -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; } } diff --git a/src/Illuminate/Testing/Constraints/Concerns/ArraySubset.php b/src/Illuminate/Testing/Constraints/Concerns/ArraySubset.php new file mode 100644 index 000000000000..b193a38bda06 --- /dev/null +++ b/src/Illuminate/Testing/Constraints/Concerns/ArraySubset.php @@ -0,0 +1,139 @@ +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; + } +} diff --git a/src/Illuminate/Testing/Constraints/Concerns/CountInDatabase.php b/src/Illuminate/Testing/Constraints/Concerns/CountInDatabase.php new file mode 100644 index 000000000000..4b2dd4d56f44 --- /dev/null +++ b/src/Illuminate/Testing/Constraints/Concerns/CountInDatabase.php @@ -0,0 +1,82 @@ +expectedCount = $expectedCount; + + $this->database = $database; + } + + /** + * Check if the expected and actual count are equal. + * + * @param string $table + * @return bool + */ + public function matches($table): bool + { + $this->actualCount = $this->database->table($table)->count(); + + return $this->actualCount === $this->expectedCount; + } + + /** + * Get the description of the failure. + * + * @param string $table + * @return string + */ + public function failureDescription($table): string + { + return sprintf( + "table [%s] matches expected entries count of %s. Entries found: %s.\n", + $table, $this->expectedCount, $this->actualCount + ); + } + + /** + * Get a string representation of the object. + * + * @param int $options + * @return string + */ + public function toString($options = 0): string + { + return (new ReflectionClass($this))->name; + } +} diff --git a/src/Illuminate/Testing/Constraints/Concerns/HasInDatabase.php b/src/Illuminate/Testing/Constraints/Concerns/HasInDatabase.php new file mode 100644 index 000000000000..f8f8d0896f70 --- /dev/null +++ b/src/Illuminate/Testing/Constraints/Concerns/HasInDatabase.php @@ -0,0 +1,122 @@ +data = $data; + + $this->database = $database; + + $this->show = 3; + } + + /** + * Check if the data is found in the given table. + * + * @param string $table + * @return bool + */ + public function matches($table): bool + { + return $this->database->table($table)->where($this->data)->count() > 0; + } + + /** + * Get the description of the failure. + * + * @param string $table + * @return string + */ + public function failureDescription($table): string + { + return sprintf( + "a row in the table [%s] matches the attributes %s.\n\n%s", + $table, $this->toString(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), $this->getAdditionalInfo($table) + ); + } + + /** + * Get additional info about the records found in the database table. + * + * @param string $table + * @return string + */ + protected function getAdditionalInfo($table) + { + $query = $this->database->table($table); + + $similarResults = $query->where( + array_key_first($this->data), + $this->data[array_key_first($this->data)] + )->select(array_keys($this->data))->limit($this->show)->get(); + + if ($similarResults->isNotEmpty()) { + $description = 'Found similar results: '.json_encode($similarResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + } else { + $query = $this->database->table($table); + + $results = $query->select(array_keys($this->data))->limit($this->show)->get(); + + if ($results->isEmpty()) { + return 'The table is empty'; + } + + $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + } + + if ($query->count() > $this->show) { + $description .= sprintf(' and %s others', $query->count() - $this->show); + } + + return $description; + } + + /** + * Get a string representation of the object. + * + * @param int $options + * @return string + */ + public function toString($options = 0): string + { + foreach ($this->data as $key => $data) { + $output[$key] = $data instanceof Expression ? $data->getValue($this->database->getQueryGrammar()) : $data; + } + + return json_encode($output ?? [], $options); + } +} diff --git a/src/Illuminate/Testing/Constraints/Concerns/NotSoftDeletedInDatabase.php b/src/Illuminate/Testing/Constraints/Concerns/NotSoftDeletedInDatabase.php new file mode 100644 index 000000000000..31c5c7641726 --- /dev/null +++ b/src/Illuminate/Testing/Constraints/Concerns/NotSoftDeletedInDatabase.php @@ -0,0 +1,119 @@ +database = $database; + + $this->data = $data; + + $this->deletedAtColumn = $deletedAtColumn; + + $this->show = 3; + } + + /** + * Check if the data is found in the given table. + * + * @param string $table + * @return bool + */ + public function matches($table): bool + { + return $this->database->table($table) + ->where($this->data) + ->whereNull($this->deletedAtColumn) + ->count() > 0; + } + + /** + * Get the description of the failure. + * + * @param string $table + * @return string + */ + public function failureDescription($table): string + { + return sprintf( + "any existing row in the table [%s] matches the attributes %s.\n\n%s", + $table, $this->toString(), $this->getAdditionalInfo($table) + ); + } + + /** + * Get additional info about the records found in the database table. + * + * @param string $table + * @return string + */ + protected function getAdditionalInfo($table) + { + $query = $this->database->table($table); + + $results = $query->limit($this->show)->get(); + + if ($results->isEmpty()) { + return 'The table is empty'; + } + + $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT); + + if ($query->count() > $this->show) { + $description .= sprintf(' and %s others', $query->count() - $this->show); + } + + return $description; + } + + /** + * Get a string representation of the object. + * + * @return string + */ + public function toString(): string + { + return json_encode($this->data); + } +} diff --git a/src/Illuminate/Testing/Constraints/Concerns/SeeInOrder.php b/src/Illuminate/Testing/Constraints/Concerns/SeeInOrder.php new file mode 100644 index 000000000000..ddb8b5b2a5d3 --- /dev/null +++ b/src/Illuminate/Testing/Constraints/Concerns/SeeInOrder.php @@ -0,0 +1,87 @@ +content = $content; + } + + /** + * Determine if the rule passes validation. + * + * @param array $values + * @return bool + */ + public function matches($values): bool + { + $position = 0; + + foreach ($values as $value) { + if (empty($value)) { + continue; + } + + $valuePosition = mb_strpos($this->content, $value, $position); + + if ($valuePosition === false || $valuePosition < $position) { + $this->failedValue = $value; + + return false; + } + + $position = $valuePosition + mb_strlen($value); + } + + return true; + } + + /** + * Get the description of the failure. + * + * @param array $values + * @return string + */ + public function failureDescription($values): string + { + return sprintf( + 'Failed asserting that \'%s\' contains "%s" in specified order.', + $this->content, + $this->failedValue + ); + } + + /** + * Get a string representation of the object. + * + * @return string + */ + public function toString(): string + { + return (new ReflectionClass($this))->name; + } +} diff --git a/src/Illuminate/Testing/Constraints/Concerns/SoftDeletedInDatabase.php b/src/Illuminate/Testing/Constraints/Concerns/SoftDeletedInDatabase.php new file mode 100644 index 000000000000..1d0bc2d4789c --- /dev/null +++ b/src/Illuminate/Testing/Constraints/Concerns/SoftDeletedInDatabase.php @@ -0,0 +1,118 @@ +data = $data; + + $this->database = $database; + + $this->deletedAtColumn = $deletedAtColumn; + + $this->show = 3; + } + + /** + * Check if the data is found in the given table. + * + * @param string $table + * @return bool + */ + public function matches($table): bool + { + return $this->database->table($table) + ->where($this->data) + ->whereNotNull($this->deletedAtColumn) + ->count() > 0; + } + + /** + * Get the description of the failure. + * + * @param string $table + * @return string + */ + public function failureDescription($table): string + { + return sprintf( + "any soft deleted row in the table [%s] matches the attributes %s.\n\n%s", + $table, $this->toString(), $this->getAdditionalInfo($table) + ); + } + + /** + * Get additional info about the records found in the database table. + * + * @param string $table + * @return string + */ + protected function getAdditionalInfo($table) + { + $query = $this->database->table($table); + + $results = $query->limit($this->show)->get(); + + if ($results->isEmpty()) { + return 'The table is empty'; + } + + $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT); + + if ($query->count() > $this->show) { + $description .= sprintf(' and %s others', $query->count() - $this->show); + } + + return $description; + } + + /** + * Get a string representation of the object. + * + * @return string + */ + public function toString(): string + { + return json_encode($this->data); + } +} diff --git a/src/Illuminate/Testing/Constraints/CountInDatabase.php b/src/Illuminate/Testing/Constraints/CountInDatabase.php index 453cca9427ab..3038e9ad4e6e 100644 --- a/src/Illuminate/Testing/Constraints/CountInDatabase.php +++ b/src/Illuminate/Testing/Constraints/CountInDatabase.php @@ -2,82 +2,17 @@ namespace Illuminate\Testing\Constraints; -use Illuminate\Database\Connection; use PHPUnit\Framework\Constraint\Constraint; -use ReflectionClass; +use PHPUnit\Runner\Version; -readonly class CountInDatabase extends Constraint -{ - /** - * The database connection. - * - * @var \Illuminate\Database\Connection - */ - protected Connection $database; - - /** - * The expected table entries count that will be checked against the actual count. - * - * @var int - */ - protected int $expectedCount; - - /** - * The actual table entries count that will be checked against the expected count. - * - * @var int|null - */ - protected int|null $actualCount; - - /** - * Create a new constraint instance. - * - * @param \Illuminate\Database\Connection $database - * @param int $expectedCount - * @return void - */ - public function __construct(Connection $database, int $expectedCount) - { - $this->expectedCount = $expectedCount; - - $this->database = $database; - } - - /** - * Check if the expected and actual count are equal. - * - * @param string $table - * @return bool - */ - public function matches($table): bool - { - $this->actualCount = $this->database->table($table)->count(); - - return $this->actualCount === $this->expectedCount; - } - - /** - * Get the description of the failure. - * - * @param string $table - * @return string - */ - public function failureDescription($table): string +if (str_starts_with(Version::series(), '10')) { + class CountInDatabase extends Constraint { - return sprintf( - "table [%s] matches expected entries count of %s. Entries found: %s.\n", - $table, $this->expectedCount, $this->actualCount - ); + use Concerns\CountInDatabase; } - - /** - * Get a string representation of the object. - * - * @param int $options - * @return string - */ - public function toString($options = 0): string +} else { + readonly class CountInDatabase extends Constraint { - return (new ReflectionClass($this))->name; + use Concerns\CountInDatabase; } } diff --git a/src/Illuminate/Testing/Constraints/HasInDatabase.php b/src/Illuminate/Testing/Constraints/HasInDatabase.php index e54ca06e2873..e92ea6f356e4 100644 --- a/src/Illuminate/Testing/Constraints/HasInDatabase.php +++ b/src/Illuminate/Testing/Constraints/HasInDatabase.php @@ -2,122 +2,17 @@ namespace Illuminate\Testing\Constraints; -use Illuminate\Contracts\Database\Query\Expression; -use Illuminate\Database\Connection; use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Runner\Version; -readonly class HasInDatabase extends Constraint -{ - /** - * Number of records that will be shown in the console in case of failure. - * - * @var int - */ - protected int $show; - - /** - * The database connection. - * - * @var \Illuminate\Database\Connection - */ - protected Connection $database; - - /** - * The data that will be used to narrow the search in the database table. - * - * @var array - */ - protected array $data; - - /** - * Create a new constraint instance. - * - * @param \Illuminate\Database\Connection $database - * @param array $data - * @return void - */ - public function __construct(Connection $database, array $data) - { - $this->data = $data; - - $this->database = $database; - - $this->show = 3; - } - - /** - * Check if the data is found in the given table. - * - * @param string $table - * @return bool - */ - public function matches($table): bool - { - return $this->database->table($table)->where($this->data)->count() > 0; - } - - /** - * Get the description of the failure. - * - * @param string $table - * @return string - */ - public function failureDescription($table): string +if (str_starts_with(Version::series(), '10')) { + class HasInDatabase extends Constraint { - return sprintf( - "a row in the table [%s] matches the attributes %s.\n\n%s", - $table, $this->toString(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), $this->getAdditionalInfo($table) - ); + use Concerns\HasInDatabase; } - - /** - * Get additional info about the records found in the database table. - * - * @param string $table - * @return string - */ - protected function getAdditionalInfo($table) +} else { + readonly class HasInDatabase extends Constraint { - $query = $this->database->table($table); - - $similarResults = $query->where( - array_key_first($this->data), - $this->data[array_key_first($this->data)] - )->select(array_keys($this->data))->limit($this->show)->get(); - - if ($similarResults->isNotEmpty()) { - $description = 'Found similar results: '.json_encode($similarResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); - } else { - $query = $this->database->table($table); - - $results = $query->select(array_keys($this->data))->limit($this->show)->get(); - - if ($results->isEmpty()) { - return 'The table is empty'; - } - - $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); - } - - if ($query->count() > $this->show) { - $description .= sprintf(' and %s others', $query->count() - $this->show); - } - - return $description; - } - - /** - * Get a string representation of the object. - * - * @param int $options - * @return string - */ - public function toString($options = 0): string - { - foreach ($this->data as $key => $data) { - $output[$key] = $data instanceof Expression ? $data->getValue($this->database->getQueryGrammar()) : $data; - } - - return json_encode($output ?? [], $options); + use Concerns\HasInDatabase; } } diff --git a/src/Illuminate/Testing/Constraints/NotSoftDeletedInDatabase.php b/src/Illuminate/Testing/Constraints/NotSoftDeletedInDatabase.php index 9dcb0911fdd1..a16c3320adcb 100644 --- a/src/Illuminate/Testing/Constraints/NotSoftDeletedInDatabase.php +++ b/src/Illuminate/Testing/Constraints/NotSoftDeletedInDatabase.php @@ -2,118 +2,17 @@ namespace Illuminate\Testing\Constraints; -use Illuminate\Database\Connection; use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Runner\Version; -readonly class NotSoftDeletedInDatabase extends Constraint -{ - /** - * Number of records that will be shown in the console in case of failure. - * - * @var int - */ - protected int $show; - - /** - * The database connection. - * - * @var \Illuminate\Database\Connection - */ - protected Connection $database; - - /** - * The data that will be used to narrow the search in the database table. - * - * @var array - */ - protected array $data; - - /** - * The name of the column that indicates soft deletion has occurred. - * - * @var string - */ - protected string $deletedAtColumn; - - /** - * Create a new constraint instance. - * - * @param \Illuminate\Database\Connection $database - * @param array $data - * @param string $deletedAtColumn - * @return void - */ - public function __construct(Connection $database, array $data, string $deletedAtColumn) - { - $this->database = $database; - - $this->data = $data; - - $this->deletedAtColumn = $deletedAtColumn; - - $this->show = 3; - } - - /** - * Check if the data is found in the given table. - * - * @param string $table - * @return bool - */ - public function matches($table): bool - { - return $this->database->table($table) - ->where($this->data) - ->whereNull($this->deletedAtColumn) - ->count() > 0; - } - - /** - * Get the description of the failure. - * - * @param string $table - * @return string - */ - public function failureDescription($table): string +if (str_starts_with(Version::series(), '10')) { + class NotSoftDeletedInDatabase extends Constraint { - return sprintf( - "any existing row in the table [%s] matches the attributes %s.\n\n%s", - $table, $this->toString(), $this->getAdditionalInfo($table) - ); + use Concerns\NotSoftDeletedInDatabase; } - - /** - * Get additional info about the records found in the database table. - * - * @param string $table - * @return string - */ - protected function getAdditionalInfo($table) - { - $query = $this->database->table($table); - - $results = $query->limit($this->show)->get(); - - if ($results->isEmpty()) { - return 'The table is empty'; - } - - $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT); - - if ($query->count() > $this->show) { - $description .= sprintf(' and %s others', $query->count() - $this->show); - } - - return $description; - } - - /** - * Get a string representation of the object. - * - * @return string - */ - public function toString(): string +} else { + readonly class NotSoftDeletedInDatabase extends Constraint { - return json_encode($this->data); + use Concerns\NotSoftDeletedInDatabase; } } diff --git a/src/Illuminate/Testing/Constraints/SeeInOrder.php b/src/Illuminate/Testing/Constraints/SeeInOrder.php index 2c8baa44668a..aab5987e692e 100644 --- a/src/Illuminate/Testing/Constraints/SeeInOrder.php +++ b/src/Illuminate/Testing/Constraints/SeeInOrder.php @@ -3,86 +3,16 @@ namespace Illuminate\Testing\Constraints; use PHPUnit\Framework\Constraint\Constraint; -use ReflectionClass; +use PHPUnit\Runner\Version; -readonly class SeeInOrder extends Constraint -{ - /** - * The string under validation. - * - * @var string - */ - protected string $content; - - /** - * The last value that failed to pass validation. - * - * @var string - */ - protected string $failedValue; - - /** - * Create a new constraint instance. - * - * @param string $content - * @return void - */ - public function __construct($content) +if (str_starts_with(Version::series(), '10')) { + class SeeInOrder extends Constraint { - $this->content = $content; + use Concerns\SeeInOrder; } - - /** - * Determine if the rule passes validation. - * - * @param array $values - * @return bool - */ - public function matches($values): bool - { - $position = 0; - - foreach ($values as $value) { - if (empty($value)) { - continue; - } - - $valuePosition = mb_strpos($this->content, $value, $position); - - if ($valuePosition === false || $valuePosition < $position) { - $this->failedValue = $value; - - return false; - } - - $position = $valuePosition + mb_strlen($value); - } - - return true; - } - - /** - * Get the description of the failure. - * - * @param array $values - * @return string - */ - public function failureDescription($values): string - { - return sprintf( - 'Failed asserting that \'%s\' contains "%s" in specified order.', - $this->content, - $this->failedValue - ); - } - - /** - * Get a string representation of the object. - * - * @return string - */ - public function toString(): string +} else { + readonly class SeeInOrder extends Constraint { - return (new ReflectionClass($this))->name; + use Concerns\SeeInOrder; } } diff --git a/src/Illuminate/Testing/Constraints/SoftDeletedInDatabase.php b/src/Illuminate/Testing/Constraints/SoftDeletedInDatabase.php index 7c2b1fc0726b..4a0f182a1aeb 100644 --- a/src/Illuminate/Testing/Constraints/SoftDeletedInDatabase.php +++ b/src/Illuminate/Testing/Constraints/SoftDeletedInDatabase.php @@ -2,118 +2,17 @@ namespace Illuminate\Testing\Constraints; -use Illuminate\Database\Connection; use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Runner\Version; -readonly class SoftDeletedInDatabase extends Constraint -{ - /** - * Number of records that will be shown in the console in case of failure. - * - * @var int - */ - protected int $show; - - /** - * The database connection. - * - * @var \Illuminate\Database\Connection - */ - protected Connection $database; - - /** - * The data that will be used to narrow the search in the database table. - * - * @var array - */ - protected array $data; - - /** - * The name of the column that indicates soft deletion has occurred. - * - * @var string - */ - protected string $deletedAtColumn; - - /** - * Create a new constraint instance. - * - * @param \Illuminate\Database\Connection $database - * @param array $data - * @param string $deletedAtColumn - * @return void - */ - public function __construct(Connection $database, array $data, string $deletedAtColumn) - { - $this->data = $data; - - $this->database = $database; - - $this->deletedAtColumn = $deletedAtColumn; - - $this->show = 3; - } - - /** - * Check if the data is found in the given table. - * - * @param string $table - * @return bool - */ - public function matches($table): bool - { - return $this->database->table($table) - ->where($this->data) - ->whereNotNull($this->deletedAtColumn) - ->count() > 0; - } - - /** - * Get the description of the failure. - * - * @param string $table - * @return string - */ - public function failureDescription($table): string +if (str_starts_with(Version::series(), '10')) { + class SoftDeletedInDatabase extends Constraint { - return sprintf( - "any soft deleted row in the table [%s] matches the attributes %s.\n\n%s", - $table, $this->toString(), $this->getAdditionalInfo($table) - ); + use Concerns\SoftDeletedInDatabase; } - - /** - * Get additional info about the records found in the database table. - * - * @param string $table - * @return string - */ - protected function getAdditionalInfo($table) - { - $query = $this->database->table($table); - - $results = $query->limit($this->show)->get(); - - if ($results->isEmpty()) { - return 'The table is empty'; - } - - $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT); - - if ($query->count() > $this->show) { - $description .= sprintf(' and %s others', $query->count() - $this->show); - } - - return $description; - } - - /** - * Get a string representation of the object. - * - * @return string - */ - public function toString(): string +} else { + readonly class SoftDeletedInDatabase extends Constraint { - return json_encode($this->data); + use Concerns\SoftDeletedInDatabase; } }