Работает обработка ссылок на таблицы с численностью
This commit is contained in:
195
vendor/sebastian/comparator/ChangeLog.md
vendored
Normal file
195
vendor/sebastian/comparator/ChangeLog.md
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
# ChangeLog
|
||||
|
||||
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
|
||||
|
||||
## [6.0.2] - 2024-08-12
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#112](https://github.com/sebastianbergmann/comparator/issues/112): Arrays with different keys and the same values are considered equal in canonicalize mode
|
||||
|
||||
## [6.0.1] - 2024-07-03
|
||||
|
||||
### Changed
|
||||
|
||||
* This project now uses PHPStan instead of Psalm for static analysis
|
||||
|
||||
## [6.0.0] - 2024-02-02
|
||||
|
||||
### Removed
|
||||
|
||||
* Removed support for PHP 8.1
|
||||
|
||||
## [5.0.2] - 2024-08-12
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#112](https://github.com/sebastianbergmann/comparator/issues/112): Arrays with different keys and the same values are considered equal in canonicalize mode
|
||||
|
||||
## [5.0.1] - 2023-08-14
|
||||
|
||||
### Fixed
|
||||
|
||||
* `MockObjectComparator` only works on instances of `PHPUnit\Framework\MockObject\MockObject`, but not on instances of `PHPUnit\Framework\MockObject\Stub`
|
||||
* `MockObjectComparator` only ignores the `$__phpunit_invocationMocker` property, but not other properties with names prefixed with `__phpunit_`
|
||||
|
||||
## [5.0.0] - 2023-02-03
|
||||
|
||||
### Changed
|
||||
|
||||
* Methods now have parameter and return type declarations
|
||||
* `Comparator::$factory` is now private, use `Comparator::factory()` instead
|
||||
* `ComparisonFailure`, `DOMNodeComparator`, `DateTimeComparator`, `ExceptionComparator`, `MockObjectComparator`, `NumericComparator`, `ResourceComparator`, `SplObjectStorageComparator`, and `TypeComparator` are now `final`
|
||||
* `ScalarComparator` and `DOMNodeComparator` now use `mb_strtolower($string, 'UTF-8')` instead of `strtolower($string)`
|
||||
|
||||
### Removed
|
||||
|
||||
* Removed `$identical` parameter from `ComparisonFailure::__construct()`
|
||||
* Removed `Comparator::$exporter`
|
||||
* Removed support for PHP 7.3, PHP 7.4, and PHP 8.0
|
||||
|
||||
## [4.0.8] - 2022-09-14
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#102](https://github.com/sebastianbergmann/comparator/pull/102): Fix `float` comparison precision
|
||||
|
||||
## [4.0.7] - 2022-09-14
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#99](https://github.com/sebastianbergmann/comparator/pull/99): Fix weak comparison between `'0'` and `false`
|
||||
|
||||
## [4.0.6] - 2020-10-26
|
||||
|
||||
### Fixed
|
||||
|
||||
* `SebastianBergmann\Comparator\Exception` now correctly extends `\Throwable`
|
||||
|
||||
## [4.0.5] - 2020-09-30
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#89](https://github.com/sebastianbergmann/comparator/pull/89): Handle PHP 8 `ValueError`
|
||||
|
||||
## [4.0.4] - 2020-09-28
|
||||
|
||||
### Changed
|
||||
|
||||
* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
|
||||
|
||||
## [4.0.3] - 2020-06-26
|
||||
|
||||
### Added
|
||||
|
||||
* This component is now supported on PHP 8
|
||||
|
||||
## [4.0.2] - 2020-06-15
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#85](https://github.com/sebastianbergmann/comparator/issues/85): Version 4.0.1 breaks backward compatibility
|
||||
|
||||
## [4.0.1] - 2020-06-15
|
||||
|
||||
### Changed
|
||||
|
||||
* Tests etc. are now ignored for archive exports
|
||||
|
||||
## [4.0.0] - 2020-02-07
|
||||
|
||||
### Removed
|
||||
|
||||
* Removed support for PHP 7.1 and PHP 7.2
|
||||
|
||||
## [3.0.5] - 2022-09-14
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#102](https://github.com/sebastianbergmann/comparator/pull/102): Fix `float` comparison precision
|
||||
|
||||
## [3.0.4] - 2022-09-14
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#99](https://github.com/sebastianbergmann/comparator/pull/99): Fix weak comparison between `'0'` and `false`
|
||||
|
||||
## [3.0.3] - 2020-11-30
|
||||
|
||||
### Changed
|
||||
|
||||
* Changed PHP version constraint in `composer.json` from `^7.1` to `>=7.1`
|
||||
|
||||
## [3.0.2] - 2018-07-12
|
||||
|
||||
### Changed
|
||||
|
||||
* By default, `MockObjectComparator` is now tried before all other (default) comparators
|
||||
|
||||
## [3.0.1] - 2018-06-14
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#53](https://github.com/sebastianbergmann/comparator/pull/53): `DOMNodeComparator` ignores `$ignoreCase` parameter
|
||||
* [#58](https://github.com/sebastianbergmann/comparator/pull/58): `ScalarComparator` does not handle extremely ugly string comparison edge cases
|
||||
|
||||
## [3.0.0] - 2018-04-18
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#48](https://github.com/sebastianbergmann/comparator/issues/48): `DateTimeComparator` does not support fractional second deltas
|
||||
|
||||
### Removed
|
||||
|
||||
* Removed support for PHP 7.0
|
||||
|
||||
## [2.1.3] - 2018-02-01
|
||||
|
||||
### Changed
|
||||
|
||||
* This component is now compatible with version 3 of `sebastian/diff`
|
||||
|
||||
## [2.1.2] - 2018-01-12
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix comparison of `DateTimeImmutable` objects
|
||||
|
||||
## [2.1.1] - 2017-12-22
|
||||
|
||||
### Fixed
|
||||
|
||||
* [phpunit/#2923](https://github.com/sebastianbergmann/phpunit/issues/2923): Unexpected failed date matching
|
||||
|
||||
## [2.1.0] - 2017-11-03
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SebastianBergmann\Comparator\Factory::reset()` to unregister all non-default comparators
|
||||
* Added support for `phpunit/phpunit-mock-objects` version `^5.0`
|
||||
|
||||
[6.0.2]: https://github.com/sebastianbergmann/comparator/compare/6.0.1...6.0.2
|
||||
[6.0.1]: https://github.com/sebastianbergmann/comparator/compare/6.0.0...6.0.1
|
||||
[6.0.0]: https://github.com/sebastianbergmann/comparator/compare/5.0...6.0.0
|
||||
[5.0.2]: https://github.com/sebastianbergmann/comparator/compare/5.0.1...5.0.2
|
||||
[5.0.1]: https://github.com/sebastianbergmann/comparator/compare/5.0.0...5.0.1
|
||||
[5.0.0]: https://github.com/sebastianbergmann/comparator/compare/4.0.8...5.0.0
|
||||
[4.0.8]: https://github.com/sebastianbergmann/comparator/compare/4.0.7...4.0.8
|
||||
[4.0.7]: https://github.com/sebastianbergmann/comparator/compare/4.0.6...4.0.7
|
||||
[4.0.6]: https://github.com/sebastianbergmann/comparator/compare/4.0.5...4.0.6
|
||||
[4.0.5]: https://github.com/sebastianbergmann/comparator/compare/4.0.4...4.0.5
|
||||
[4.0.4]: https://github.com/sebastianbergmann/comparator/compare/4.0.3...4.0.4
|
||||
[4.0.3]: https://github.com/sebastianbergmann/comparator/compare/4.0.2...4.0.3
|
||||
[4.0.2]: https://github.com/sebastianbergmann/comparator/compare/4.0.1...4.0.2
|
||||
[4.0.1]: https://github.com/sebastianbergmann/comparator/compare/4.0.0...4.0.1
|
||||
[4.0.0]: https://github.com/sebastianbergmann/comparator/compare/3.0.5...4.0.0
|
||||
[3.0.5]: https://github.com/sebastianbergmann/comparator/compare/3.0.4...3.0.5
|
||||
[3.0.4]: https://github.com/sebastianbergmann/comparator/compare/3.0.3...3.0.4
|
||||
[3.0.3]: https://github.com/sebastianbergmann/comparator/compare/3.0.2...3.0.3
|
||||
[3.0.2]: https://github.com/sebastianbergmann/comparator/compare/3.0.1...3.0.2
|
||||
[3.0.1]: https://github.com/sebastianbergmann/comparator/compare/3.0.0...3.0.1
|
||||
[3.0.0]: https://github.com/sebastianbergmann/comparator/compare/2.1.3...3.0.0
|
||||
[2.1.3]: https://github.com/sebastianbergmann/comparator/compare/2.1.2...2.1.3
|
||||
[2.1.2]: https://github.com/sebastianbergmann/comparator/compare/2.1.1...2.1.2
|
||||
[2.1.1]: https://github.com/sebastianbergmann/comparator/compare/2.1.0...2.1.1
|
||||
[2.1.0]: https://github.com/sebastianbergmann/comparator/compare/2.0.2...2.1.0
|
29
vendor/sebastian/comparator/LICENSE
vendored
Normal file
29
vendor/sebastian/comparator/LICENSE
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2002-2024, Sebastian Bergmann
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
42
vendor/sebastian/comparator/README.md
vendored
Normal file
42
vendor/sebastian/comparator/README.md
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
[](https://packagist.org/packages/sebastian/comparator)
|
||||
[](https://github.com/sebastianbergmann/comparator/actions)
|
||||
[](https://codecov.io/gh/sebastianbergmann/comparator)
|
||||
|
||||
# sebastian/comparator
|
||||
|
||||
This component provides the functionality to compare PHP values for equality.
|
||||
|
||||
## Installation
|
||||
|
||||
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
|
||||
|
||||
```
|
||||
composer require sebastian/comparator
|
||||
```
|
||||
|
||||
If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
|
||||
|
||||
```
|
||||
composer require --dev sebastian/comparator
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```php
|
||||
<?php
|
||||
use SebastianBergmann\Comparator\Factory;
|
||||
use SebastianBergmann\Comparator\ComparisonFailure;
|
||||
|
||||
$date1 = new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York'));
|
||||
$date2 = new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago'));
|
||||
|
||||
$factory = new Factory;
|
||||
$comparator = $factory->getComparatorFor($date1, $date2);
|
||||
|
||||
try {
|
||||
$comparator->assertEquals($date1, $date2);
|
||||
print "Dates match";
|
||||
} catch (ComparisonFailure $failure) {
|
||||
print "Dates don't match";
|
||||
}
|
||||
```
|
30
vendor/sebastian/comparator/SECURITY.md
vendored
Normal file
30
vendor/sebastian/comparator/SECURITY.md
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# Security Policy
|
||||
|
||||
If you believe you have found a security vulnerability in the library that is developed in this repository, please report it to us through coordinated disclosure.
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
|
||||
|
||||
Instead, please email `sebastian@phpunit.de`.
|
||||
|
||||
Please include as much of the information listed below as you can to help us better understand and resolve the issue:
|
||||
|
||||
* The type of issue
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
## Web Context
|
||||
|
||||
The library that is developed in this repository was either extracted from [PHPUnit](https://github.com/sebastianbergmann/phpunit) or developed specifically as a dependency for PHPUnit.
|
||||
|
||||
The library is developed with a focus on development environments and the command-line. No specific testing or hardening with regard to using the library in an HTTP or web context or with untrusted input data is performed. The library might also contain functionality that intentionally exposes internal application data for debugging purposes.
|
||||
|
||||
If the library is used in a web application, the application developer is responsible for filtering inputs or escaping outputs as necessary and for verifying that the used functionality is safe for use within the intended context.
|
||||
|
||||
Vulnerabilities specific to the use outside a development context will be fixed as applicable, provided that the fix does not have an averse effect on the primary use case for development purposes.
|
||||
|
63
vendor/sebastian/comparator/composer.json
vendored
Normal file
63
vendor/sebastian/comparator/composer.json
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
"description": "Provides the functionality to compare PHP values for equality",
|
||||
"keywords": ["comparator","compare","equality"],
|
||||
"homepage": "https://github.com/sebastianbergmann/comparator",
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
},
|
||||
{
|
||||
"name": "Jeff Welch",
|
||||
"email": "whatthejeff@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Volker Dusch",
|
||||
"email": "github@wallbash.com"
|
||||
},
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@2bepublished.at"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/comparator/issues",
|
||||
"security": "https://github.com/sebastianbergmann/comparator/security/policy"
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"sebastian/diff": "^6.0",
|
||||
"sebastian/exporter": "^6.0",
|
||||
"ext-dom": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^11.0"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "8.2.0"
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"classmap": [
|
||||
"tests/_fixture"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "6.0-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
137
vendor/sebastian/comparator/src/ArrayComparator.php
vendored
Normal file
137
vendor/sebastian/comparator/src/ArrayComparator.php
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function array_is_list;
|
||||
use function array_key_exists;
|
||||
use function assert;
|
||||
use function is_array;
|
||||
use function sort;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use function trim;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
|
||||
/**
|
||||
* Arrays are equal if they contain the same key-value pairs.
|
||||
* The order of the keys does not matter.
|
||||
* The types of key-value pairs do not matter.
|
||||
*/
|
||||
class ArrayComparator extends Comparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return is_array($expected) && is_array($actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $processed
|
||||
*
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false, array &$processed = []): void
|
||||
{
|
||||
assert(is_array($expected));
|
||||
assert(is_array($actual));
|
||||
|
||||
if ($canonicalize) {
|
||||
if (array_is_list($expected)) {
|
||||
sort($expected);
|
||||
}
|
||||
|
||||
if (array_is_list($actual)) {
|
||||
sort($actual);
|
||||
}
|
||||
}
|
||||
|
||||
$remaining = $actual;
|
||||
$actualAsString = "Array (\n";
|
||||
$expectedAsString = "Array (\n";
|
||||
$equal = true;
|
||||
$exporter = new Exporter;
|
||||
|
||||
foreach ($expected as $key => $value) {
|
||||
unset($remaining[$key]);
|
||||
|
||||
if (!array_key_exists($key, $actual)) {
|
||||
$expectedAsString .= sprintf(
|
||||
" %s => %s\n",
|
||||
$exporter->export($key),
|
||||
$exporter->shortenedExport($value),
|
||||
);
|
||||
|
||||
$equal = false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$comparator = $this->factory()->getComparatorFor($value, $actual[$key]);
|
||||
|
||||
/** @phpstan-ignore arguments.count */
|
||||
$comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
|
||||
|
||||
$expectedAsString .= sprintf(
|
||||
" %s => %s\n",
|
||||
$exporter->export($key),
|
||||
$exporter->shortenedExport($value),
|
||||
);
|
||||
|
||||
$actualAsString .= sprintf(
|
||||
" %s => %s\n",
|
||||
$exporter->export($key),
|
||||
$exporter->shortenedExport($actual[$key]),
|
||||
);
|
||||
} catch (ComparisonFailure $e) {
|
||||
$expectedAsString .= sprintf(
|
||||
" %s => %s\n",
|
||||
$exporter->export($key),
|
||||
$e->getExpectedAsString() ? $this->indent($e->getExpectedAsString()) : $exporter->shortenedExport($e->getExpected()),
|
||||
);
|
||||
|
||||
$actualAsString .= sprintf(
|
||||
" %s => %s\n",
|
||||
$exporter->export($key),
|
||||
$e->getActualAsString() ? $this->indent($e->getActualAsString()) : $exporter->shortenedExport($e->getActual()),
|
||||
);
|
||||
|
||||
$equal = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($remaining as $key => $value) {
|
||||
$actualAsString .= sprintf(
|
||||
" %s => %s\n",
|
||||
$exporter->export($key),
|
||||
$exporter->shortenedExport($value),
|
||||
);
|
||||
|
||||
$equal = false;
|
||||
}
|
||||
|
||||
$expectedAsString .= ')';
|
||||
$actualAsString .= ')';
|
||||
|
||||
if (!$equal) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$expectedAsString,
|
||||
$actualAsString,
|
||||
'Failed asserting that two arrays are equal.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function indent(string $lines): string
|
||||
{
|
||||
return trim(str_replace("\n", "\n ", $lines));
|
||||
}
|
||||
}
|
32
vendor/sebastian/comparator/src/Comparator.php
vendored
Normal file
32
vendor/sebastian/comparator/src/Comparator.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
abstract class Comparator
|
||||
{
|
||||
private Factory $factory;
|
||||
|
||||
public function setFactory(Factory $factory): void
|
||||
{
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
abstract public function accepts(mixed $expected, mixed $actual): bool;
|
||||
|
||||
/**
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
abstract public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false): void;
|
||||
|
||||
protected function factory(): Factory
|
||||
{
|
||||
return $this->factory;
|
||||
}
|
||||
}
|
68
vendor/sebastian/comparator/src/ComparisonFailure.php
vendored
Normal file
68
vendor/sebastian/comparator/src/ComparisonFailure.php
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\Diff\Differ;
|
||||
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
|
||||
|
||||
final class ComparisonFailure extends RuntimeException
|
||||
{
|
||||
private mixed $expected;
|
||||
private mixed $actual;
|
||||
private string $expectedAsString;
|
||||
private string $actualAsString;
|
||||
|
||||
public function __construct(mixed $expected, mixed $actual, string $expectedAsString, string $actualAsString, string $message = '')
|
||||
{
|
||||
parent::__construct($message);
|
||||
|
||||
$this->expected = $expected;
|
||||
$this->actual = $actual;
|
||||
$this->expectedAsString = $expectedAsString;
|
||||
$this->actualAsString = $actualAsString;
|
||||
}
|
||||
|
||||
public function getActual(): mixed
|
||||
{
|
||||
return $this->actual;
|
||||
}
|
||||
|
||||
public function getExpected(): mixed
|
||||
{
|
||||
return $this->expected;
|
||||
}
|
||||
|
||||
public function getActualAsString(): string
|
||||
{
|
||||
return $this->actualAsString;
|
||||
}
|
||||
|
||||
public function getExpectedAsString(): string
|
||||
{
|
||||
return $this->expectedAsString;
|
||||
}
|
||||
|
||||
public function getDiff(): string
|
||||
{
|
||||
if (!$this->actualAsString && !$this->expectedAsString) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$differ = new Differ(new UnifiedDiffOutputBuilder("\n--- Expected\n+++ Actual\n"));
|
||||
|
||||
return $differ->diff($this->expectedAsString, $this->actualAsString);
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->getMessage() . $this->getDiff();
|
||||
}
|
||||
}
|
98
vendor/sebastian/comparator/src/DOMNodeComparator.php
vendored
Normal file
98
vendor/sebastian/comparator/src/DOMNodeComparator.php
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function assert;
|
||||
use function mb_strtolower;
|
||||
use function sprintf;
|
||||
use DOMDocument;
|
||||
use DOMNode;
|
||||
use ValueError;
|
||||
|
||||
final class DOMNodeComparator extends ObjectComparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return $expected instanceof DOMNode && $actual instanceof DOMNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $processed
|
||||
*
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false, array &$processed = []): void
|
||||
{
|
||||
assert($expected instanceof DOMNode);
|
||||
assert($actual instanceof DOMNode);
|
||||
|
||||
$expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
|
||||
$actualAsString = $this->nodeToText($actual, true, $ignoreCase);
|
||||
|
||||
if ($expectedAsString !== $actualAsString) {
|
||||
$type = $expected instanceof DOMDocument ? 'documents' : 'nodes';
|
||||
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$expectedAsString,
|
||||
$actualAsString,
|
||||
sprintf("Failed asserting that two DOM %s are equal.\n", $type),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the normalized, whitespace-cleaned, and indented textual
|
||||
* representation of a DOMNode.
|
||||
*/
|
||||
private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase): string
|
||||
{
|
||||
if ($canonicalize) {
|
||||
$document = new DOMDocument;
|
||||
|
||||
try {
|
||||
$c14n = $node->C14N();
|
||||
|
||||
assert(!empty($c14n));
|
||||
|
||||
@$document->loadXML($c14n);
|
||||
} catch (ValueError) {
|
||||
}
|
||||
|
||||
$node = $document;
|
||||
}
|
||||
|
||||
if ($node instanceof DOMDocument) {
|
||||
$document = $node;
|
||||
} else {
|
||||
$document = $node->ownerDocument;
|
||||
}
|
||||
|
||||
assert($document instanceof DOMDocument);
|
||||
|
||||
$document->formatOutput = true;
|
||||
$document->normalizeDocument();
|
||||
|
||||
if ($node instanceof DOMDocument) {
|
||||
$text = $node->saveXML();
|
||||
} else {
|
||||
$text = $document->saveXML($node);
|
||||
}
|
||||
|
||||
assert($text !== false);
|
||||
|
||||
if ($ignoreCase) {
|
||||
return mb_strtolower($text, 'UTF-8');
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
64
vendor/sebastian/comparator/src/DateTimeComparator.php
vendored
Normal file
64
vendor/sebastian/comparator/src/DateTimeComparator.php
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function abs;
|
||||
use function assert;
|
||||
use function floor;
|
||||
use function sprintf;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
|
||||
final class DateTimeComparator extends ObjectComparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return ($expected instanceof DateTime || $expected instanceof DateTimeImmutable) &&
|
||||
($actual instanceof DateTime || $actual instanceof DateTimeImmutable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $processed
|
||||
*
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false, array &$processed = []): void
|
||||
{
|
||||
assert($expected instanceof DateTime || $expected instanceof DateTimeImmutable);
|
||||
assert($actual instanceof DateTime || $actual instanceof DateTimeImmutable);
|
||||
|
||||
$absDelta = abs($delta);
|
||||
$delta = new DateInterval(sprintf('PT%dS', $absDelta));
|
||||
$delta->f = $absDelta - floor($absDelta);
|
||||
|
||||
$actualClone = (clone $actual)
|
||||
->setTimezone(new DateTimeZone('UTC'));
|
||||
|
||||
$expectedLower = (clone $expected)
|
||||
->setTimezone(new DateTimeZone('UTC'))
|
||||
->sub($delta);
|
||||
|
||||
$expectedUpper = (clone $expected)
|
||||
->setTimezone(new DateTimeZone('UTC'))
|
||||
->add($delta);
|
||||
|
||||
if ($actualClone < $expectedLower || $actualClone > $expectedUpper) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$expected->format('Y-m-d\TH:i:s.uO'),
|
||||
$actual->format('Y-m-d\TH:i:s.uO'),
|
||||
'Failed asserting that two DateTime objects are equal.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
44
vendor/sebastian/comparator/src/ExceptionComparator.php
vendored
Normal file
44
vendor/sebastian/comparator/src/ExceptionComparator.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function assert;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Compares Exception instances for equality.
|
||||
*/
|
||||
final class ExceptionComparator extends ObjectComparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return $expected instanceof Exception && $actual instanceof Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function toArray(object $object): array
|
||||
{
|
||||
assert($object instanceof Exception);
|
||||
|
||||
$array = parent::toArray($object);
|
||||
|
||||
unset(
|
||||
$array['file'],
|
||||
$array['line'],
|
||||
$array['trace'],
|
||||
$array['string'],
|
||||
$array['xdebug_message'],
|
||||
);
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
114
vendor/sebastian/comparator/src/Factory.php
vendored
Normal file
114
vendor/sebastian/comparator/src/Factory.php
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function array_unshift;
|
||||
|
||||
final class Factory
|
||||
{
|
||||
private static ?Factory $instance = null;
|
||||
|
||||
/**
|
||||
* @var list<Comparator>
|
||||
*/
|
||||
private array $customComparators = [];
|
||||
|
||||
/**
|
||||
* @var list<Comparator>
|
||||
*/
|
||||
private array $defaultComparators = [];
|
||||
|
||||
public static function getInstance(): self
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->registerDefaultComparators();
|
||||
}
|
||||
|
||||
public function getComparatorFor(mixed $expected, mixed $actual): Comparator
|
||||
{
|
||||
foreach ($this->customComparators as $comparator) {
|
||||
if ($comparator->accepts($expected, $actual)) {
|
||||
return $comparator;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->defaultComparators as $comparator) {
|
||||
if ($comparator->accepts($expected, $actual)) {
|
||||
return $comparator;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException('No suitable Comparator implementation found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new comparator.
|
||||
*
|
||||
* This comparator will be returned by getComparatorFor() if its accept() method
|
||||
* returns TRUE for the compared values. It has higher priority than the
|
||||
* existing comparators, meaning that its accept() method will be invoked
|
||||
* before those of the other comparators.
|
||||
*/
|
||||
public function register(Comparator $comparator): void
|
||||
{
|
||||
array_unshift($this->customComparators, $comparator);
|
||||
|
||||
$comparator->setFactory($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a comparator.
|
||||
*
|
||||
* This comparator will no longer be considered by getComparatorFor().
|
||||
*/
|
||||
public function unregister(Comparator $comparator): void
|
||||
{
|
||||
foreach ($this->customComparators as $key => $_comparator) {
|
||||
if ($comparator === $_comparator) {
|
||||
unset($this->customComparators[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->customComparators = [];
|
||||
}
|
||||
|
||||
private function registerDefaultComparators(): void
|
||||
{
|
||||
$this->registerDefaultComparator(new MockObjectComparator);
|
||||
$this->registerDefaultComparator(new DateTimeComparator);
|
||||
$this->registerDefaultComparator(new DOMNodeComparator);
|
||||
$this->registerDefaultComparator(new SplObjectStorageComparator);
|
||||
$this->registerDefaultComparator(new ExceptionComparator);
|
||||
$this->registerDefaultComparator(new ObjectComparator);
|
||||
$this->registerDefaultComparator(new ResourceComparator);
|
||||
$this->registerDefaultComparator(new ArrayComparator);
|
||||
$this->registerDefaultComparator(new NumericComparator);
|
||||
$this->registerDefaultComparator(new ScalarComparator);
|
||||
$this->registerDefaultComparator(new TypeComparator);
|
||||
}
|
||||
|
||||
private function registerDefaultComparator(Comparator $comparator): void
|
||||
{
|
||||
$this->defaultComparators[] = $comparator;
|
||||
|
||||
$comparator->setFactory($this);
|
||||
}
|
||||
}
|
46
vendor/sebastian/comparator/src/MockObjectComparator.php
vendored
Normal file
46
vendor/sebastian/comparator/src/MockObjectComparator.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function array_keys;
|
||||
use function assert;
|
||||
use function str_starts_with;
|
||||
use PHPUnit\Framework\MockObject\Stub;
|
||||
|
||||
/**
|
||||
* Compares PHPUnit\Framework\MockObject\MockObject instances for equality.
|
||||
*/
|
||||
final class MockObjectComparator extends ObjectComparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return $expected instanceof Stub && $actual instanceof Stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function toArray(object $object): array
|
||||
{
|
||||
assert($object instanceof Stub);
|
||||
|
||||
$array = parent::toArray($object);
|
||||
|
||||
foreach (array_keys($array) as $key) {
|
||||
if (!str_starts_with($key, '__phpunit_')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset($array[$key]);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
67
vendor/sebastian/comparator/src/NumericComparator.php
vendored
Normal file
67
vendor/sebastian/comparator/src/NumericComparator.php
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function abs;
|
||||
use function is_float;
|
||||
use function is_infinite;
|
||||
use function is_nan;
|
||||
use function is_numeric;
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
|
||||
final class NumericComparator extends ScalarComparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
// all numerical values, but not if both of them are strings
|
||||
return is_numeric($expected) && is_numeric($actual) &&
|
||||
!(is_string($expected) && is_string($actual));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false): void
|
||||
{
|
||||
if ($this->isInfinite($actual) && $this->isInfinite($expected)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (($this->isInfinite($actual) xor $this->isInfinite($expected)) ||
|
||||
($this->isNan($actual) || $this->isNan($expected)) ||
|
||||
abs($actual - $expected) > $delta) {
|
||||
$exporter = new Exporter;
|
||||
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
'',
|
||||
'',
|
||||
sprintf(
|
||||
'Failed asserting that %s matches expected %s.',
|
||||
$exporter->export($actual),
|
||||
$exporter->export($expected),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function isInfinite(mixed $value): bool
|
||||
{
|
||||
return is_float($value) && is_infinite($value);
|
||||
}
|
||||
|
||||
private function isNan(mixed $value): bool
|
||||
{
|
||||
return is_float($value) && is_nan($value);
|
||||
}
|
||||
}
|
93
vendor/sebastian/comparator/src/ObjectComparator.php
vendored
Normal file
93
vendor/sebastian/comparator/src/ObjectComparator.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function assert;
|
||||
use function in_array;
|
||||
use function is_object;
|
||||
use function sprintf;
|
||||
use function substr_replace;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
|
||||
class ObjectComparator extends ArrayComparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return is_object($expected) && is_object($actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $processed
|
||||
*
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false, array &$processed = []): void
|
||||
{
|
||||
assert(is_object($expected));
|
||||
assert(is_object($actual));
|
||||
|
||||
if ($actual::class !== $expected::class) {
|
||||
$exporter = new Exporter;
|
||||
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$exporter->export($expected),
|
||||
$exporter->export($actual),
|
||||
sprintf(
|
||||
'%s is not instance of expected class "%s".',
|
||||
$exporter->export($actual),
|
||||
$expected::class,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// don't compare twice to allow for cyclic dependencies
|
||||
if (in_array([$actual, $expected], $processed, true) ||
|
||||
in_array([$expected, $actual], $processed, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$processed[] = [$actual, $expected];
|
||||
|
||||
// don't compare objects if they are identical
|
||||
// this helps to avoid the error "maximum function nesting level reached"
|
||||
// CAUTION: this conditional clause is not tested
|
||||
if ($actual !== $expected) {
|
||||
try {
|
||||
parent::assertEquals(
|
||||
$this->toArray($expected),
|
||||
$this->toArray($actual),
|
||||
$delta,
|
||||
$canonicalize,
|
||||
$ignoreCase,
|
||||
$processed,
|
||||
);
|
||||
} catch (ComparisonFailure $e) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
// replace "Array" with "MyClass object"
|
||||
substr_replace($e->getExpectedAsString(), $expected::class . ' Object', 0, 5),
|
||||
substr_replace($e->getActualAsString(), $actual::class . ' Object', 0, 5),
|
||||
'Failed asserting that two objects are equal.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function toArray(object $object): array
|
||||
{
|
||||
return (new Exporter)->toArray($object);
|
||||
}
|
||||
}
|
42
vendor/sebastian/comparator/src/ResourceComparator.php
vendored
Normal file
42
vendor/sebastian/comparator/src/ResourceComparator.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function assert;
|
||||
use function is_resource;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
|
||||
final class ResourceComparator extends Comparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return is_resource($expected) && is_resource($actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false): void
|
||||
{
|
||||
assert(is_resource($expected));
|
||||
assert(is_resource($actual));
|
||||
|
||||
$exporter = new Exporter;
|
||||
|
||||
if ($actual != $expected) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$exporter->export($expected),
|
||||
$exporter->export($actual),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
84
vendor/sebastian/comparator/src/ScalarComparator.php
vendored
Normal file
84
vendor/sebastian/comparator/src/ScalarComparator.php
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function is_bool;
|
||||
use function is_object;
|
||||
use function is_scalar;
|
||||
use function is_string;
|
||||
use function mb_strtolower;
|
||||
use function method_exists;
|
||||
use function sprintf;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
|
||||
/**
|
||||
* Compares scalar or NULL values for equality.
|
||||
*/
|
||||
class ScalarComparator extends Comparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return ((is_scalar($expected) xor null === $expected) &&
|
||||
(is_scalar($actual) xor null === $actual)) ||
|
||||
// allow comparison between strings and objects featuring __toString()
|
||||
(is_string($expected) && is_object($actual) && method_exists($actual, '__toString')) ||
|
||||
(is_object($expected) && method_exists($expected, '__toString') && is_string($actual));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false): void
|
||||
{
|
||||
$expectedToCompare = $expected;
|
||||
$actualToCompare = $actual;
|
||||
$exporter = new Exporter;
|
||||
|
||||
// always compare as strings to avoid strange behaviour
|
||||
// otherwise 0 == 'Foobar'
|
||||
if ((is_string($expected) && !is_bool($actual)) || (is_string($actual) && !is_bool($expected))) {
|
||||
/** @phpstan-ignore cast.string */
|
||||
$expectedToCompare = (string) $expectedToCompare;
|
||||
|
||||
/** @phpstan-ignore cast.string */
|
||||
$actualToCompare = (string) $actualToCompare;
|
||||
|
||||
if ($ignoreCase) {
|
||||
$expectedToCompare = mb_strtolower($expectedToCompare, 'UTF-8');
|
||||
$actualToCompare = mb_strtolower($actualToCompare, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
if ($expectedToCompare !== $actualToCompare && is_string($expected) && is_string($actual)) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$exporter->export($expected),
|
||||
$exporter->export($actual),
|
||||
'Failed asserting that two strings are equal.',
|
||||
);
|
||||
}
|
||||
|
||||
if ($expectedToCompare != $actualToCompare) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
// no diff is required
|
||||
'',
|
||||
'',
|
||||
sprintf(
|
||||
'Failed asserting that %s matches expected %s.',
|
||||
$exporter->export($actual),
|
||||
$exporter->export($expected),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
57
vendor/sebastian/comparator/src/SplObjectStorageComparator.php
vendored
Normal file
57
vendor/sebastian/comparator/src/SplObjectStorageComparator.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function assert;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
use SplObjectStorage;
|
||||
|
||||
final class SplObjectStorageComparator extends Comparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false): void
|
||||
{
|
||||
assert($expected instanceof SplObjectStorage);
|
||||
assert($actual instanceof SplObjectStorage);
|
||||
|
||||
$exporter = new Exporter;
|
||||
|
||||
foreach ($actual as $object) {
|
||||
if (!$expected->contains($object)) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$exporter->export($expected),
|
||||
$exporter->export($actual),
|
||||
'Failed asserting that two objects are equal.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($expected as $object) {
|
||||
if (!$actual->contains($object)) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
$exporter->export($expected),
|
||||
$exporter->export($actual),
|
||||
'Failed asserting that two objects are equal.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/sebastian/comparator/src/TypeComparator.php
vendored
Normal file
43
vendor/sebastian/comparator/src/TypeComparator.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use function gettype;
|
||||
use function sprintf;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
|
||||
final class TypeComparator extends Comparator
|
||||
{
|
||||
public function accepts(mixed $expected, mixed $actual): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ComparisonFailure
|
||||
*/
|
||||
public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false): void
|
||||
{
|
||||
if (gettype($expected) != gettype($actual)) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
// we don't need a diff
|
||||
'',
|
||||
'',
|
||||
sprintf(
|
||||
'%s does not match expected type "%s".',
|
||||
(new Exporter)->shortenedExport($actual),
|
||||
gettype($expected),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
16
vendor/sebastian/comparator/src/exceptions/Exception.php
vendored
Normal file
16
vendor/sebastian/comparator/src/exceptions/Exception.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
use Throwable;
|
||||
|
||||
interface Exception extends Throwable
|
||||
{
|
||||
}
|
14
vendor/sebastian/comparator/src/exceptions/RuntimeException.php
vendored
Normal file
14
vendor/sebastian/comparator/src/exceptions/RuntimeException.php
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of sebastian/comparator.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\Comparator;
|
||||
|
||||
final class RuntimeException extends \RuntimeException implements Exception
|
||||
{
|
||||
}
|
Reference in New Issue
Block a user