Upgrade framework

This commit is contained in:
2023-11-14 16:54:35 +01:00
parent 1648a5cd42
commit 4fcf6fffcc
10548 changed files with 693138 additions and 466698 deletions

View File

@@ -0,0 +1,15 @@
# ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
## [1.0.1] - 2020-09-28
### Changed
* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
## [1.0.0] - 2020-08-12
* Initial release
[1.0.0]: https://github.com/sebastianbergmann/cli-parser/compare/bb7bb3297957927962b0a3335befe7b66f7462e9...1.0.0

33
vendor/sebastian/cli-parser/LICENSE vendored Normal file
View File

@@ -0,0 +1,33 @@
sebastian/cli-parser
Copyright (c) 2020, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Sebastian Bergmann nor the names of his
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 OWNER 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.

17
vendor/sebastian/cli-parser/README.md vendored Normal file
View File

@@ -0,0 +1,17 @@
# sebastian/cli-parser
Library for parsing `$_SERVER['argv']`, extracted from `phpunit/phpunit`.
## Installation
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
```
composer require sebastian/cli-parser
```
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/cli-parser
```

View File

@@ -0,0 +1,41 @@
{
"name": "sebastian/cli-parser",
"description": "Library for parsing CLI options",
"type": "library",
"homepage": "https://github.com/sebastianbergmann/cli-parser",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/cli-parser/issues"
},
"prefer-stable": true,
"require": {
"php": ">=7.3"
},
"require-dev": {
"phpunit/phpunit": "^9.3"
},
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
}
}

View File

@@ -0,0 +1,12 @@
{
"source": {
"directories": [
"src"
]
},
"mutators": {
"@default": true
},
"minMsi": 100,
"minCoveredMsi": 100
}

View File

@@ -0,0 +1,204 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/cli-parser.
*
* (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\CliParser;
use function array_map;
use function array_merge;
use function array_shift;
use function array_slice;
use function assert;
use function count;
use function current;
use function explode;
use function is_array;
use function is_int;
use function is_string;
use function key;
use function next;
use function preg_replace;
use function reset;
use function sort;
use function strlen;
use function strpos;
use function strstr;
use function substr;
final class Parser
{
/**
* @psalm-param list<string> $argv
* @psalm-param list<string> $longOptions
*
* @throws AmbiguousOptionException
* @throws RequiredOptionArgumentMissingException
* @throws OptionDoesNotAllowArgumentException
* @throws UnknownOptionException
*/
public function parse(array $argv, string $shortOptions, array $longOptions = null): array
{
if (empty($argv)) {
return [[], []];
}
$options = [];
$nonOptions = [];
if ($longOptions) {
sort($longOptions);
}
if (isset($argv[0][0]) && $argv[0][0] !== '-') {
array_shift($argv);
}
reset($argv);
$argv = array_map('trim', $argv);
while (false !== $arg = current($argv)) {
$i = key($argv);
assert(is_int($i));
next($argv);
if ($arg === '') {
continue;
}
if ($arg === '--') {
$nonOptions = array_merge($nonOptions, array_slice($argv, $i + 1));
break;
}
if ($arg[0] !== '-' || (strlen($arg) > 1 && $arg[1] === '-' && !$longOptions)) {
$nonOptions[] = $arg;
continue;
}
if (strlen($arg) > 1 && $arg[1] === '-' && is_array($longOptions)) {
$this->parseLongOption(
substr($arg, 2),
$longOptions,
$options,
$argv
);
} else {
$this->parseShortOption(
substr($arg, 1),
$shortOptions,
$options,
$argv
);
}
}
return [$options, $nonOptions];
}
/**
* @throws RequiredOptionArgumentMissingException
*/
private function parseShortOption(string $arg, string $shortOptions, array &$opts, array &$args): void
{
$argLength = strlen($arg);
for ($i = 0; $i < $argLength; $i++) {
$option = $arg[$i];
$optionArgument = null;
if ($arg[$i] === ':' || ($spec = strstr($shortOptions, $option)) === false) {
throw new UnknownOptionException('-' . $option);
}
assert(is_string($spec));
if (strlen($spec) > 1 && $spec[1] === ':') {
if ($i + 1 < $argLength) {
$opts[] = [$option, substr($arg, $i + 1)];
break;
}
if (!(strlen($spec) > 2 && $spec[2] === ':')) {
$optionArgument = current($args);
if (!$optionArgument) {
throw new RequiredOptionArgumentMissingException('-' . $option);
}
assert(is_string($optionArgument));
next($args);
}
}
$opts[] = [$option, $optionArgument];
}
}
/**
* @psalm-param list<string> $longOptions
*
* @throws AmbiguousOptionException
* @throws RequiredOptionArgumentMissingException
* @throws OptionDoesNotAllowArgumentException
* @throws UnknownOptionException
*/
private function parseLongOption(string $arg, array $longOptions, array &$opts, array &$args): void
{
$count = count($longOptions);
$list = explode('=', $arg);
$option = $list[0];
$optionArgument = null;
if (count($list) > 1) {
$optionArgument = $list[1];
}
$optionLength = strlen($option);
foreach ($longOptions as $i => $longOption) {
$opt_start = substr($longOption, 0, $optionLength);
if ($opt_start !== $option) {
continue;
}
$opt_rest = substr($longOption, $optionLength);
if ($opt_rest !== '' && $i + 1 < $count && $option[0] !== '=' && strpos($longOptions[$i + 1], $option) === 0) {
throw new AmbiguousOptionException('--' . $option);
}
if (substr($longOption, -1) === '=') {
/* @noinspection StrlenInEmptyStringCheckContextInspection */
if (substr($longOption, -2) !== '==' && !strlen((string) $optionArgument)) {
if (false === $optionArgument = current($args)) {
throw new RequiredOptionArgumentMissingException('--' . $option);
}
next($args);
}
} elseif ($optionArgument) {
throw new OptionDoesNotAllowArgumentException('--' . $option);
}
$fullOption = '--' . preg_replace('/={1,2}$/', '', $longOption);
$opts[] = [$fullOption, $optionArgument];
return;
}
throw new UnknownOptionException('--' . $option);
}
}

View File

@@ -0,0 +1,26 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/cli-parser.
*
* (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\CliParser;
use function sprintf;
use RuntimeException;
final class AmbiguousOptionException extends RuntimeException implements Exception
{
public function __construct(string $option)
{
parent::__construct(
sprintf(
'Option "%s" is ambiguous',
$option
)
);
}
}

View File

@@ -1,17 +1,16 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the GlobalState package.
* This file is part of sebastian/cli-parser.
*
* (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\CliParser;
namespace SebastianBergmann\GlobalState\TestFixture;
use Throwable;
/**
*/
class BlacklistedChildClass extends BlacklistedClass
interface Exception extends Throwable
{
}

View File

@@ -0,0 +1,26 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/cli-parser.
*
* (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\CliParser;
use function sprintf;
use RuntimeException;
final class OptionDoesNotAllowArgumentException extends RuntimeException implements Exception
{
public function __construct(string $option)
{
parent::__construct(
sprintf(
'Option "%s" does not allow an argument',
$option
)
);
}
}

View File

@@ -0,0 +1,26 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/cli-parser.
*
* (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\CliParser;
use function sprintf;
use RuntimeException;
final class RequiredOptionArgumentMissingException extends RuntimeException implements Exception
{
public function __construct(string $option)
{
parent::__construct(
sprintf(
'Required argument for option "%s" is missing',
$option
)
);
}
}

View File

@@ -0,0 +1,26 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/cli-parser.
*
* (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\CliParser;
use function sprintf;
use RuntimeException;
final class UnknownOptionException extends RuntimeException implements Exception
{
public function __construct(string $option)
{
parent::__construct(
sprintf(
'Unknown option "%s"',
$option
)
);
}
}

View File

@@ -1,4 +0,0 @@
/.idea
/composer.lock
/vendor

View File

@@ -1,67 +0,0 @@
<?php
$finder = Symfony\CS\Finder\DefaultFinder::create()
->files()
->in('src')
->in('tests')
->name('*.php');
return Symfony\CS\Config\Config::create()
->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
->fixers(
array(
'align_double_arrow',
'align_equals',
'braces',
'concat_with_spaces',
'duplicate_semicolon',
'elseif',
'empty_return',
'encoding',
'eof_ending',
'extra_empty_lines',
'function_call_space',
'function_declaration',
'indentation',
'join_function',
'line_after_namespace',
'linefeed',
'list_commas',
'lowercase_constants',
'lowercase_keywords',
'method_argument_space',
'multiple_use',
'namespace_no_leading_whitespace',
'no_blank_lines_after_class_opening',
'no_empty_lines_after_phpdocs',
'parenthesis',
'php_closing_tag',
'phpdoc_indent',
'phpdoc_no_access',
'phpdoc_no_empty_return',
'phpdoc_no_package',
'phpdoc_params',
'phpdoc_scalar',
'phpdoc_separation',
'phpdoc_to_comment',
'phpdoc_trim',
'phpdoc_types',
'phpdoc_var_without_name',
'remove_lines_between_uses',
'return',
'self_accessor',
'short_array_syntax',
'short_tag',
'single_line_after_imports',
'single_quote',
'spaces_before_semicolon',
'spaces_cast',
'ternary_spaces',
'trailing_spaces',
'trim_array_spaces',
'unused_use',
'visibility',
'whitespacy_lines'
)
)
->finder($finder);

View File

@@ -1,25 +0,0 @@
language: php
php:
- 5.6
- 7.0
- 7.0snapshot
- 7.1
- 7.1snapshot
- master
sudo: false
before_install:
- composer self-update
- composer clear-cache
install:
- travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable
script:
- ./vendor/bin/phpunit
notifications:
email: false

View File

@@ -2,9 +2,37 @@
All notable changes to `sebastianbergmann/code-unit-reverse-lookup` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [2.0.3] - 2020-09-28
### Changed
* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
## [2.0.2] - 2020-06-26
### Added
* This component is now supported on PHP 8
## [2.0.1] - 2020-06-15
### Changed
* Tests etc. are now ignored for archive exports
## 2.0.0 - 2020-02-07
### Removed
* This component is no longer supported on PHP 5.6, PHP 7.0, PHP 7.1, and PHP 7.2
## 1.0.0 - 2016-02-13
### Added
* Initial release
[2.0.3]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.2...2.0.3
[2.0.2]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/1.0.0...2.0.0

View File

@@ -1,6 +1,6 @@
code-unit-reverse-lookup
Copyright (c) 2016-2017, Sebastian Bergmann <sebastian@phpunit.de>.
Copyright (c) 2016-2020, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -1,4 +1,7 @@
# code-unit-reverse-lookup
# sebastian/code-unit-reverse-lookup
[![CI Status](https://github.com/sebastianbergmann/code-unit-reverse-lookup/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/code-unit-reverse-lookup/actions)
[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/code-unit-reverse-lookup/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/code-unit-reverse-lookup)
Looks up which function or method a line of code belongs to.
@@ -6,9 +9,12 @@ Looks up which function or method a line of code belongs to.
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
composer require sebastian/code-unit-reverse-lookup
```
composer require sebastian/code-unit-reverse-lookup
```
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/code-unit-reverse-lookup
```
composer require --dev sebastian/code-unit-reverse-lookup
```

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="code-unit-reverse-lookup" default="setup">
<target name="setup" depends="clean,composer"/>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/vendor"/>
<delete file="${basedir}/composer.lock"/>
</target>
<target name="composer" depends="clean" description="Install dependencies with Composer">
<exec executable="composer" taskname="composer">
<arg value="update"/>
<arg value="--no-interaction"/>
<arg value="--no-progress"/>
<arg value="--no-ansi"/>
<arg value="--no-suggest"/>
<arg value="--optimize-autoloader"/>
<arg value="--prefer-stable"/>
</exec>
</target>
</project>

View File

@@ -9,11 +9,19 @@
"email": "sebastian@phpunit.de"
}
],
"prefer-stable": true,
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"require": {
"php": "^5.6 || ^7.0"
"php": ">=7.3"
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.0"
"phpunit/phpunit": "^9.3"
},
"autoload": {
"classmap": [
@@ -22,7 +30,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "2.0-dev"
}
}
}

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.4/phpunit.xsd"
bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
verbose="true">
<testsuite>
<directory suffix="Test.php">tests</directory>
</testsuite>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -1,15 +1,26 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of code-unit-reverse-lookup.
* This file is part of sebastian/code-unit-reverse-lookup.
*
* (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\CodeUnitReverseLookup;
use function array_merge;
use function assert;
use function get_declared_classes;
use function get_declared_traits;
use function get_defined_functions;
use function is_array;
use function range;
use ReflectionClass;
use ReflectionFunction;
use ReflectionFunctionAbstract;
use ReflectionMethod;
/**
* @since Class available since Release 1.0.0
*/
@@ -44,25 +55,31 @@ class Wizard
if (isset($this->lookupTable[$filename][$lineNumber])) {
return $this->lookupTable[$filename][$lineNumber];
} else {
return $filename . ':' . $lineNumber;
}
return $filename . ':' . $lineNumber;
}
private function updateLookupTable()
private function updateLookupTable(): void
{
$this->processClassesAndTraits();
$this->processFunctions();
}
private function processClassesAndTraits()
private function processClassesAndTraits(): void
{
foreach (array_merge(get_declared_classes(), get_declared_traits()) as $classOrTrait) {
$classes = get_declared_classes();
$traits = get_declared_traits();
assert(is_array($classes));
assert(is_array($traits));
foreach (array_merge($classes, $traits) as $classOrTrait) {
if (isset($this->processedClasses[$classOrTrait])) {
continue;
}
$reflector = new \ReflectionClass($classOrTrait);
$reflector = new ReflectionClass($classOrTrait);
foreach ($reflector->getMethods() as $method) {
$this->processFunctionOrMethod($method);
@@ -72,23 +89,20 @@ class Wizard
}
}
private function processFunctions()
private function processFunctions(): void
{
foreach (get_defined_functions()['user'] as $function) {
if (isset($this->processedFunctions[$function])) {
continue;
}
$this->processFunctionOrMethod(new \ReflectionFunction($function));
$this->processFunctionOrMethod(new ReflectionFunction($function));
$this->processedFunctions[$function] = true;
}
}
/**
* @param \ReflectionFunctionAbstract $functionOrMethod
*/
private function processFunctionOrMethod(\ReflectionFunctionAbstract $functionOrMethod)
private function processFunctionOrMethod(ReflectionFunctionAbstract $functionOrMethod): void
{
if ($functionOrMethod->isInternal()) {
return;
@@ -96,7 +110,7 @@ class Wizard
$name = $functionOrMethod->getName();
if ($functionOrMethod instanceof \ReflectionMethod) {
if ($functionOrMethod instanceof ReflectionMethod) {
$name = $functionOrMethod->getDeclaringClass()->getName() . '::' . $name;
}

View File

@@ -1,45 +0,0 @@
<?php
/*
* This file is part of code-unit-reverse-lookup.
*
* (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\CodeUnitReverseLookup;
use PHPUnit\Framework\TestCase;
/**
* @covers SebastianBergmann\CodeUnitReverseLookup\Wizard
*/
class WizardTest extends TestCase
{
/**
* @var Wizard
*/
private $wizard;
protected function setUp()
{
$this->wizard = new Wizard;
}
public function testMethodCanBeLookedUp()
{
$this->assertEquals(
__METHOD__,
$this->wizard->lookup(__FILE__, __LINE__)
);
}
public function testReturnsFilenameAndLineNumberAsStringWhenNotInCodeUnit()
{
$this->assertEquals(
'file.php:1',
$this->wizard->lookup('file.php', 1)
);
}
}

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44">
<file src="src/Mapper.php">
<ArgumentTypeCoercion occurrences="16">
<code>$firstPart</code>
<code>$firstPart</code>
<code>$firstPart</code>
<code>$firstPart</code>
<code>$firstPart</code>
<code>$firstPart</code>
<code>$firstPart</code>
<code>$firstPart</code>
<code>$firstPart</code>
<code>$secondPart</code>
<code>$unit</code>
<code>$unit</code>
<code>$unit</code>
<code>$unit</code>
<code>$unit</code>
<code>$unit</code>
</ArgumentTypeCoercion>
</file>
</files>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<psalm
totallyTyped="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
resolveFromConfigFile="false"
errorBaseline=".psalm/baseline.xml"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

65
vendor/sebastian/code-unit/ChangeLog.md vendored Normal file
View File

@@ -0,0 +1,65 @@
# ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [1.0.8] - 2020-10-26
### Fixed
* `SebastianBergmann\CodeUnit\Exception` now correctly extends `\Throwable`
## [1.0.7] - 2020-10-02
### Fixed
* `SebastianBergmann\CodeUnit\Mapper::stringToCodeUnits()` no longer attempts to create `CodeUnit` objects for code units that are not declared in userland
## [1.0.6] - 2020-09-28
### Changed
* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
## [1.0.5] - 2020-06-26
### Fixed
* [#3](https://github.com/sebastianbergmann/code-unit/issues/3): Regression in 1.0.4
## [1.0.4] - 2020-06-26
### Added
* This component is now supported on PHP 8
## [1.0.3] - 2020-06-15
### Changed
* Tests etc. are now ignored for archive exports
## [1.0.2] - 2020-04-30
### Fixed
* `Mapper::stringToCodeUnits()` raised the wrong exception for `Class::method` when a class named `Class` exists but does not have a method named `method`
## [1.0.1] - 2020-04-27
### Fixed
* [#2](https://github.com/sebastianbergmann/code-unit/issues/2): `Mapper::stringToCodeUnits()` breaks when `ClassName<extended>` is used for class that extends built-in class
## [1.0.0] - 2020-03-30
* Initial release
[1.0.8]: https://github.com/sebastianbergmann/code-unit/compare/1.0.7...1.0.8
[1.0.7]: https://github.com/sebastianbergmann/code-unit/compare/1.0.6...1.0.7
[1.0.6]: https://github.com/sebastianbergmann/code-unit/compare/1.0.5...1.0.6
[1.0.5]: https://github.com/sebastianbergmann/code-unit/compare/1.0.4...1.0.5
[1.0.4]: https://github.com/sebastianbergmann/code-unit/compare/1.0.3...1.0.4
[1.0.3]: https://github.com/sebastianbergmann/code-unit/compare/1.0.2...1.0.3
[1.0.2]: https://github.com/sebastianbergmann/code-unit/compare/1.0.1...1.0.2
[1.0.1]: https://github.com/sebastianbergmann/code-unit/compare/1.0.0...1.0.1
[1.0.0]: https://github.com/sebastianbergmann/code-unit/compare/530c3900e5db9bcb8516da545bef0d62536cedaa...1.0.0

33
vendor/sebastian/code-unit/LICENSE vendored Normal file
View File

@@ -0,0 +1,33 @@
sebastian/code-unit
Copyright (c) 2020, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Sebastian Bergmann nor the names of his
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 OWNER 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.

17
vendor/sebastian/code-unit/README.md vendored Normal file
View File

@@ -0,0 +1,17 @@
# sebastian/code-unit
Collection of value objects that represent the PHP code units.
## Installation
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
```
composer require sebastian/code-unit
```
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/code-unit
```

View File

@@ -0,0 +1,50 @@
{
"name": "sebastian/code-unit",
"description": "Collection of value objects that represent the PHP code units",
"type": "library",
"homepage": "https://github.com/sebastianbergmann/code-unit",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/code-unit/issues"
},
"prefer-stable": true,
"require": {
"php": ">=7.3"
},
"require-dev": {
"phpunit/phpunit": "^9.3"
},
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"autoload": {
"classmap": [
"src/"
]
},
"autoload-dev": {
"classmap": [
"tests/_fixture"
],
"files": [
"tests/_fixture/file_with_multiple_code_units.php",
"tests/_fixture/function.php"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
/**
* @psalm-immutable
*/
final class ClassMethodUnit extends CodeUnit
{
/**
* @psalm-assert-if-true ClassMethodUnit $this
*/
public function isClassMethod(): bool
{
return true;
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
/**
* @psalm-immutable
*/
final class ClassUnit extends CodeUnit
{
/**
* @psalm-assert-if-true ClassUnit $this
*/
public function isClass(): bool
{
return true;
}
}

View File

@@ -0,0 +1,445 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
use function range;
use function sprintf;
use ReflectionClass;
use ReflectionFunction;
use ReflectionMethod;
/**
* @psalm-immutable
*/
abstract class CodeUnit
{
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $sourceFileName;
/**
* @var array
* @psalm-var list<int>
*/
private $sourceLines;
/**
* @psalm-param class-string $className
*
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public static function forClass(string $className): ClassUnit
{
self::ensureUserDefinedClass($className);
$reflector = self::reflectorForClass($className);
return new ClassUnit(
$className,
$reflector->getFileName(),
range(
$reflector->getStartLine(),
$reflector->getEndLine()
)
);
}
/**
* @psalm-param class-string $className
*
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public static function forClassMethod(string $className, string $methodName): ClassMethodUnit
{
self::ensureUserDefinedClass($className);
$reflector = self::reflectorForClassMethod($className, $methodName);
return new ClassMethodUnit(
$className . '::' . $methodName,
$reflector->getFileName(),
range(
$reflector->getStartLine(),
$reflector->getEndLine()
)
);
}
/**
* @psalm-param class-string $interfaceName
*
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public static function forInterface(string $interfaceName): InterfaceUnit
{
self::ensureUserDefinedInterface($interfaceName);
$reflector = self::reflectorForClass($interfaceName);
return new InterfaceUnit(
$interfaceName,
$reflector->getFileName(),
range(
$reflector->getStartLine(),
$reflector->getEndLine()
)
);
}
/**
* @psalm-param class-string $interfaceName
*
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public static function forInterfaceMethod(string $interfaceName, string $methodName): InterfaceMethodUnit
{
self::ensureUserDefinedInterface($interfaceName);
$reflector = self::reflectorForClassMethod($interfaceName, $methodName);
return new InterfaceMethodUnit(
$interfaceName . '::' . $methodName,
$reflector->getFileName(),
range(
$reflector->getStartLine(),
$reflector->getEndLine()
)
);
}
/**
* @psalm-param class-string $traitName
*
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public static function forTrait(string $traitName): TraitUnit
{
self::ensureUserDefinedTrait($traitName);
$reflector = self::reflectorForClass($traitName);
return new TraitUnit(
$traitName,
$reflector->getFileName(),
range(
$reflector->getStartLine(),
$reflector->getEndLine()
)
);
}
/**
* @psalm-param class-string $traitName
*
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public static function forTraitMethod(string $traitName, string $methodName): TraitMethodUnit
{
self::ensureUserDefinedTrait($traitName);
$reflector = self::reflectorForClassMethod($traitName, $methodName);
return new TraitMethodUnit(
$traitName . '::' . $methodName,
$reflector->getFileName(),
range(
$reflector->getStartLine(),
$reflector->getEndLine()
)
);
}
/**
* @psalm-param callable-string $functionName
*
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public static function forFunction(string $functionName): FunctionUnit
{
$reflector = self::reflectorForFunction($functionName);
if (!$reflector->isUserDefined()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is not a user-defined function',
$functionName
)
);
}
return new FunctionUnit(
$functionName,
$reflector->getFileName(),
range(
$reflector->getStartLine(),
$reflector->getEndLine()
)
);
}
/**
* @psalm-param list<int> $sourceLines
*/
private function __construct(string $name, string $sourceFileName, array $sourceLines)
{
$this->name = $name;
$this->sourceFileName = $sourceFileName;
$this->sourceLines = $sourceLines;
}
public function name(): string
{
return $this->name;
}
public function sourceFileName(): string
{
return $this->sourceFileName;
}
/**
* @psalm-return list<int>
*/
public function sourceLines(): array
{
return $this->sourceLines;
}
public function isClass(): bool
{
return false;
}
public function isClassMethod(): bool
{
return false;
}
public function isInterface(): bool
{
return false;
}
public function isInterfaceMethod(): bool
{
return false;
}
public function isTrait(): bool
{
return false;
}
public function isTraitMethod(): bool
{
return false;
}
public function isFunction(): bool
{
return false;
}
/**
* @psalm-param class-string $className
*
* @throws InvalidCodeUnitException
*/
private static function ensureUserDefinedClass(string $className): void
{
try {
$reflector = new ReflectionClass($className);
if ($reflector->isInterface()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is an interface and not a class',
$className
)
);
}
if ($reflector->isTrait()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is a trait and not a class',
$className
)
);
}
if (!$reflector->isUserDefined()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is not a user-defined class',
$className
)
);
}
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @psalm-param class-string $interfaceName
*
* @throws InvalidCodeUnitException
*/
private static function ensureUserDefinedInterface(string $interfaceName): void
{
try {
$reflector = new ReflectionClass($interfaceName);
if (!$reflector->isInterface()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is not an interface',
$interfaceName
)
);
}
if (!$reflector->isUserDefined()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is not a user-defined interface',
$interfaceName
)
);
}
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @psalm-param class-string $traitName
*
* @throws InvalidCodeUnitException
*/
private static function ensureUserDefinedTrait(string $traitName): void
{
try {
$reflector = new ReflectionClass($traitName);
if (!$reflector->isTrait()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is not a trait',
$traitName
)
);
}
// @codeCoverageIgnoreStart
if (!$reflector->isUserDefined()) {
throw new InvalidCodeUnitException(
sprintf(
'"%s" is not a user-defined trait',
$traitName
)
);
}
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private static function reflectorForClass(string $className): ReflectionClass
{
try {
return new ReflectionClass($className);
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private static function reflectorForClassMethod(string $className, string $methodName): ReflectionMethod
{
try {
return new ReflectionMethod($className, $methodName);
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @psalm-param callable-string $functionName
*
* @throws ReflectionException
*/
private static function reflectorForFunction(string $functionName): ReflectionFunction
{
try {
return new ReflectionFunction($functionName);
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
}

View File

@@ -0,0 +1,84 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
use function array_merge;
use function count;
use Countable;
use IteratorAggregate;
final class CodeUnitCollection implements Countable, IteratorAggregate
{
/**
* @psalm-var list<CodeUnit>
*/
private $codeUnits = [];
/**
* @psalm-param list<CodeUnit> $items
*/
public static function fromArray(array $items): self
{
$collection = new self;
foreach ($items as $item) {
$collection->add($item);
}
return $collection;
}
public static function fromList(CodeUnit ...$items): self
{
return self::fromArray($items);
}
private function __construct()
{
}
/**
* @psalm-return list<CodeUnit>
*/
public function asArray(): array
{
return $this->codeUnits;
}
public function getIterator(): CodeUnitCollectionIterator
{
return new CodeUnitCollectionIterator($this);
}
public function count(): int
{
return count($this->codeUnits);
}
public function isEmpty(): bool
{
return empty($this->codeUnits);
}
public function mergeWith(self $other): self
{
return self::fromArray(
array_merge(
$this->asArray(),
$other->asArray()
)
);
}
private function add(CodeUnit $item): void
{
$this->codeUnits[] = $item;
}
}

View File

@@ -0,0 +1,55 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
use Iterator;
final class CodeUnitCollectionIterator implements Iterator
{
/**
* @psalm-var list<CodeUnit>
*/
private $codeUnits;
/**
* @var int
*/
private $position = 0;
public function __construct(CodeUnitCollection $collection)
{
$this->codeUnits = $collection->asArray();
}
public function rewind(): void
{
$this->position = 0;
}
public function valid(): bool
{
return isset($this->codeUnits[$this->position]);
}
public function key(): int
{
return $this->position;
}
public function current(): CodeUnit
{
return $this->codeUnits[$this->position];
}
public function next(): void
{
$this->position++;
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
/**
* @psalm-immutable
*/
final class FunctionUnit extends CodeUnit
{
/**
* @psalm-assert-if-true FunctionUnit $this
*/
public function isFunction(): bool
{
return true;
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
/**
* @psalm-immutable
*/
final class InterfaceMethodUnit extends CodeUnit
{
/**
* @psalm-assert-if-true InterfaceMethod $this
*/
public function isInterfaceMethod(): bool
{
return true;
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
/**
* @psalm-immutable
*/
final class InterfaceUnit extends CodeUnit
{
/**
* @psalm-assert-if-true InterfaceUnit $this
*/
public function isInterface(): bool
{
return true;
}
}

View File

@@ -0,0 +1,414 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
use function array_keys;
use function array_merge;
use function array_unique;
use function array_values;
use function class_exists;
use function explode;
use function function_exists;
use function interface_exists;
use function ksort;
use function method_exists;
use function sort;
use function sprintf;
use function str_replace;
use function strpos;
use function trait_exists;
use ReflectionClass;
use ReflectionFunction;
use ReflectionMethod;
final class Mapper
{
/**
* @psalm-return array<string,list<int>>
*/
public function codeUnitsToSourceLines(CodeUnitCollection $codeUnits): array
{
$result = [];
foreach ($codeUnits as $codeUnit) {
$sourceFileName = $codeUnit->sourceFileName();
if (!isset($result[$sourceFileName])) {
$result[$sourceFileName] = [];
}
$result[$sourceFileName] = array_merge($result[$sourceFileName], $codeUnit->sourceLines());
}
foreach (array_keys($result) as $sourceFileName) {
$result[$sourceFileName] = array_values(array_unique($result[$sourceFileName]));
sort($result[$sourceFileName]);
}
ksort($result);
return $result;
}
/**
* @throws InvalidCodeUnitException
* @throws ReflectionException
*/
public function stringToCodeUnits(string $unit): CodeUnitCollection
{
if (strpos($unit, '::') !== false) {
[$firstPart, $secondPart] = explode('::', $unit);
if (empty($firstPart) && $this->isUserDefinedFunction($secondPart)) {
return CodeUnitCollection::fromList(CodeUnit::forFunction($secondPart));
}
if ($this->isUserDefinedClass($firstPart)) {
if ($secondPart === '<public>') {
return $this->publicMethodsOfClass($firstPart);
}
if ($secondPart === '<!public>') {
return $this->protectedAndPrivateMethodsOfClass($firstPart);
}
if ($secondPart === '<protected>') {
return $this->protectedMethodsOfClass($firstPart);
}
if ($secondPart === '<!protected>') {
return $this->publicAndPrivateMethodsOfClass($firstPart);
}
if ($secondPart === '<private>') {
return $this->privateMethodsOfClass($firstPart);
}
if ($secondPart === '<!private>') {
return $this->publicAndProtectedMethodsOfClass($firstPart);
}
if ($this->isUserDefinedMethod($firstPart, $secondPart)) {
return CodeUnitCollection::fromList(CodeUnit::forClassMethod($firstPart, $secondPart));
}
}
if ($this->isUserDefinedInterface($firstPart)) {
return CodeUnitCollection::fromList(CodeUnit::forInterfaceMethod($firstPart, $secondPart));
}
if ($this->isUserDefinedTrait($firstPart)) {
return CodeUnitCollection::fromList(CodeUnit::forTraitMethod($firstPart, $secondPart));
}
} else {
if ($this->isUserDefinedClass($unit)) {
$units = [CodeUnit::forClass($unit)];
foreach ($this->reflectorForClass($unit)->getTraits() as $trait) {
if (!$trait->isUserDefined()) {
// @codeCoverageIgnoreStart
continue;
// @codeCoverageIgnoreEnd
}
$units[] = CodeUnit::forTrait($trait->getName());
}
return CodeUnitCollection::fromArray($units);
}
if ($this->isUserDefinedInterface($unit)) {
return CodeUnitCollection::fromList(CodeUnit::forInterface($unit));
}
if ($this->isUserDefinedTrait($unit)) {
return CodeUnitCollection::fromList(CodeUnit::forTrait($unit));
}
if ($this->isUserDefinedFunction($unit)) {
return CodeUnitCollection::fromList(CodeUnit::forFunction($unit));
}
$unit = str_replace('<extended>', '', $unit);
if ($this->isUserDefinedClass($unit)) {
return $this->classAndParentClassesAndTraits($unit);
}
}
throw new InvalidCodeUnitException(
sprintf(
'"%s" is not a valid code unit',
$unit
)
);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function publicMethodsOfClass(string $className): CodeUnitCollection
{
return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function publicAndProtectedMethodsOfClass(string $className): CodeUnitCollection
{
return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function publicAndPrivateMethodsOfClass(string $className): CodeUnitCollection
{
return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PRIVATE);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function protectedMethodsOfClass(string $className): CodeUnitCollection
{
return $this->methodsOfClass($className, ReflectionMethod::IS_PROTECTED);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function protectedAndPrivateMethodsOfClass(string $className): CodeUnitCollection
{
return $this->methodsOfClass($className, ReflectionMethod::IS_PROTECTED | ReflectionMethod::IS_PRIVATE);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function privateMethodsOfClass(string $className): CodeUnitCollection
{
return $this->methodsOfClass($className, ReflectionMethod::IS_PRIVATE);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function methodsOfClass(string $className, int $filter): CodeUnitCollection
{
$units = [];
foreach ($this->reflectorForClass($className)->getMethods($filter) as $method) {
if (!$method->isUserDefined()) {
continue;
}
$units[] = CodeUnit::forClassMethod($className, $method->getName());
}
return CodeUnitCollection::fromArray($units);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function classAndParentClassesAndTraits(string $className): CodeUnitCollection
{
$units = [CodeUnit::forClass($className)];
$reflector = $this->reflectorForClass($className);
foreach ($this->reflectorForClass($className)->getTraits() as $trait) {
if (!$trait->isUserDefined()) {
// @codeCoverageIgnoreStart
continue;
// @codeCoverageIgnoreEnd
}
$units[] = CodeUnit::forTrait($trait->getName());
}
while ($reflector = $reflector->getParentClass()) {
if (!$reflector->isUserDefined()) {
break;
}
$units[] = CodeUnit::forClass($reflector->getName());
foreach ($reflector->getTraits() as $trait) {
if (!$trait->isUserDefined()) {
// @codeCoverageIgnoreStart
continue;
// @codeCoverageIgnoreEnd
}
$units[] = CodeUnit::forTrait($trait->getName());
}
}
return CodeUnitCollection::fromArray($units);
}
/**
* @psalm-param class-string $className
*
* @throws ReflectionException
*/
private function reflectorForClass(string $className): ReflectionClass
{
try {
return new ReflectionClass($className);
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @throws ReflectionException
*/
private function isUserDefinedFunction(string $functionName): bool
{
if (!function_exists($functionName)) {
return false;
}
try {
return (new ReflectionFunction($functionName))->isUserDefined();
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @throws ReflectionException
*/
private function isUserDefinedClass(string $className): bool
{
if (!class_exists($className)) {
return false;
}
try {
return (new ReflectionClass($className))->isUserDefined();
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @throws ReflectionException
*/
private function isUserDefinedInterface(string $interfaceName): bool
{
if (!interface_exists($interfaceName)) {
return false;
}
try {
return (new ReflectionClass($interfaceName))->isUserDefined();
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @throws ReflectionException
*/
private function isUserDefinedTrait(string $traitName): bool
{
if (!trait_exists($traitName)) {
return false;
}
try {
return (new ReflectionClass($traitName))->isUserDefined();
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
/**
* @throws ReflectionException
*/
private function isUserDefinedMethod(string $className, string $methodName): bool
{
if (!class_exists($className)) {
// @codeCoverageIgnoreStart
return false;
// @codeCoverageIgnoreEnd
}
if (!method_exists($className, $methodName)) {
// @codeCoverageIgnoreStart
return false;
// @codeCoverageIgnoreEnd
}
try {
return (new ReflectionMethod($className, $methodName))->isUserDefined();
// @codeCoverageIgnoreStart
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
// @codeCoverageIgnoreEnd
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
/**
* @psalm-immutable
*/
final class TraitMethodUnit extends CodeUnit
{
/**
* @psalm-assert-if-true TraitMethodUnit $this
*/
public function isTraitMethod(): bool
{
return true;
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
/**
* @psalm-immutable
*/
final class TraitUnit extends CodeUnit
{
/**
* @psalm-assert-if-true TraitUnit $this
*/
public function isTrait(): bool
{
return true;
}
}

View File

@@ -1,17 +1,16 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the GlobalState package.
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
namespace SebastianBergmann\GlobalState\TestFixture;
use Throwable;
/**
*/
trait SnapshotTrait
interface Exception extends Throwable
{
}

View File

@@ -0,0 +1,16 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
use RuntimeException;
final class InvalidCodeUnitException extends RuntimeException implements Exception
{
}

View File

@@ -0,0 +1,16 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
use RuntimeException;
final class NoTraitException extends RuntimeException implements Exception
{
}

View File

@@ -0,0 +1,16 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/code-unit.
*
* (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\CodeUnit;
use RuntimeException;
final class ReflectionException extends RuntimeException implements Exception
{
}

View File

@@ -1,6 +0,0 @@
/build/coverage
/composer.lock
/composer.phar
/phpunit.xml
/.idea
/vendor

View File

@@ -1,25 +0,0 @@
language: php
sudo: false
install:
- travis_retry composer install --no-interaction --prefer-source
script: ./vendor/bin/phpunit --configuration ./build/travis-ci.xml
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
notifications:
email: false
webhooks:
urls:
- https://webhooks.gitter.im/e/6668f52f3dd4e3f81960
on_success: always
on_failure: always
on_start: false

143
vendor/sebastian/comparator/ChangeLog.md vendored Normal file
View File

@@ -0,0 +1,143 @@
# ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [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`
[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

View File

@@ -1,6 +1,6 @@
Comparator
Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
Copyright (c) 2002-2020, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -1,6 +1,7 @@
[![Build Status](https://travis-ci.org/sebastianbergmann/comparator.svg?branch=master)](https://travis-ci.org/sebastianbergmann/comparator)
# sebastian/comparator
# Comparator
[![CI Status](https://github.com/sebastianbergmann/comparator/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/comparator/actions)
[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/comparator/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/comparator)
This component provides the functionality to compare PHP values for equality.
@@ -8,11 +9,15 @@ This component provides the functionality to compare PHP values for equality.
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
composer require sebastian/comparator
```
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
```
composer require --dev sebastian/comparator
```
## Usage
@@ -30,10 +35,7 @@ $comparator = $factory->getComparatorFor($date1, $date2);
try {
$comparator->assertEquals($date1, $date2);
print "Dates match";
}
catch (ComparisonFailure $failure) {
} catch (ComparisonFailure $failure) {
print "Dates don't match";
}
```

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="comparator">
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/vendor"/>
<delete file="${basedir}/composer.lock"/>
</target>
<target name="composer" depends="clean" description="Install dependencies with Composer">
<tstamp>
<format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
</tstamp>
<delete>
<fileset dir="${basedir}">
<include name="composer.phar" />
<date datetime="${thirty.days.ago}" when="before"/>
</fileset>
</delete>
<get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
<exec executable="php">
<arg value="composer.phar"/>
<arg value="install"/>
</exec>
</target>
<target name="phpab" description="Generate autoloader script">
<exec executable="phpab">
<arg value="--output" />
<arg path="tests/autoload.php" />
<arg path="tests" />
</exec>
</target>
</project>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.2/phpunit.xsd"
bootstrap="../tests/bootstrap.php"
backupGlobals="false"
verbose="true">
<testsuite name="Comparator">
<directory suffix="Test.php">../tests</directory>
</testsuite>
</phpunit>

View File

@@ -2,7 +2,7 @@
"name": "sebastian/comparator",
"description": "Provides the functionality to compare PHP values for equality",
"keywords": ["comparator","compare","equality"],
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"homepage": "https://github.com/sebastianbergmann/comparator",
"license": "BSD-3-Clause",
"authors": [
{
@@ -22,22 +22,35 @@
"email": "bschussek@2bepublished.at"
}
],
"prefer-stable": true,
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.2",
"sebastian/exporter": "~1.2 || ~2.0"
"php": ">=7.3",
"sebastian/diff": "^4.0",
"sebastian/exporter": "^4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
"phpunit/phpunit": "^9.3"
},
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"autoload": {
"classmap": [
"src/"
]
},
"autoload-dev": {
"classmap": [
"tests/_fixture"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
"dev-master": "4.0-dev"
}
}
}

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
bootstrap="tests/bootstrap.php"
backupGlobals="false"
verbose="true">
<testsuite name="Comparator">
<directory suffix="Test.php">tests</directory>
</testsuite>
<logging>
<log type="coverage-html" target="build/coverage"/>
</logging>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -1,25 +1,36 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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_key_exists;
use function is_array;
use function sort;
use function sprintf;
use function str_replace;
use function trim;
/**
* Compares arrays for equality.
*
* 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
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
@@ -28,7 +39,7 @@ class ArrayComparator extends Comparator
}
/**
* Asserts that two values are equal.
* Asserts that two arrays are equal.
*
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
@@ -39,22 +50,23 @@ class ArrayComparator extends Comparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
{
if ($canonicalize) {
sort($expected);
sort($actual);
}
$remaining = $actual;
$expString = $actString = "Array (\n";
$equal = true;
$remaining = $actual;
$actualAsString = "Array (\n";
$expectedAsString = "Array (\n";
$equal = true;
foreach ($expected as $key => $value) {
unset($remaining[$key]);
if (!array_key_exists($key, $actual)) {
$expString .= sprintf(
$expectedAsString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
@@ -69,31 +81,28 @@ class ArrayComparator extends Comparator
$comparator = $this->factory->getComparatorFor($value, $actual[$key]);
$comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
$expString .= sprintf(
$expectedAsString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
);
$actString .= sprintf(
$actualAsString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($actual[$key])
);
} catch (ComparisonFailure $e) {
$expString .= sprintf(
$expectedAsString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$e->getExpectedAsString()
? $this->indent($e->getExpectedAsString())
: $this->exporter->shortenedExport($e->getExpected())
$e->getExpectedAsString() ? $this->indent($e->getExpectedAsString()) : $this->exporter->shortenedExport($e->getExpected())
);
$actString .= sprintf(
$actualAsString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$e->getActualAsString()
? $this->indent($e->getActualAsString())
: $this->exporter->shortenedExport($e->getActual())
$e->getActualAsString() ? $this->indent($e->getActualAsString()) : $this->exporter->shortenedExport($e->getActual())
);
$equal = false;
@@ -101,7 +110,7 @@ class ArrayComparator extends Comparator
}
foreach ($remaining as $key => $value) {
$actString .= sprintf(
$actualAsString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
@@ -110,15 +119,15 @@ class ArrayComparator extends Comparator
$equal = false;
}
$expString .= ')';
$actString .= ')';
$expectedAsString .= ')';
$actualAsString .= ')';
if (!$equal) {
throw new ComparisonFailure(
$expected,
$actual,
$expString,
$actString,
$expectedAsString,
$actualAsString,
false,
'Failed asserting that two arrays are equal.'
);

View File

@@ -1,13 +1,12 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 SebastianBergmann\Exporter\Exporter;
@@ -32,10 +31,7 @@ abstract class Comparator
$this->exporter = new Exporter;
}
/**
* @param Factory $factory
*/
public function setFactory(Factory $factory)
public function setFactory(Factory $factory)/*: void*/
{
$this->factory = $factory;
}
@@ -43,8 +39,9 @@ abstract class Comparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
abstract public function accepts($expected, $actual);

View File

@@ -1,42 +1,47 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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;
/**
* Thrown when an assertion for string equality failed.
*/
class ComparisonFailure extends \RuntimeException
class ComparisonFailure extends RuntimeException
{
/**
* Expected value of the retrieval which does not match $actual.
*
* @var mixed
*/
protected $expected;
/**
* Actually retrieved value which does not match $expected.
*
* @var mixed
*/
protected $actual;
/**
* The string representation of the expected value
* The string representation of the expected value.
*
* @var string
*/
protected $expectedAsString;
/**
* The string representation of the actual value
* The string representation of the actual value.
*
* @var string
*/
protected $actualAsString;
@@ -49,6 +54,7 @@ class ComparisonFailure extends \RuntimeException
/**
* Optional message which is placed in front of the first line
* returned by toString().
*
* @var string
*/
protected $message;
@@ -56,13 +62,13 @@ class ComparisonFailure extends \RuntimeException
/**
* Initialises with the expected value and the actual value.
*
* @param mixed $expected Expected value retrieved.
* @param mixed $actual Actual value retrieved.
* @param mixed $expected expected value retrieved
* @param mixed $actual actual value retrieved
* @param string $expectedAsString
* @param string $actualAsString
* @param bool $identical
* @param string $message A string which is prefixed on all returned lines
* in the difference output.
* @param string $message a string which is prefixed on all returned lines
* in the difference output
*/
public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = false, $message = '')
{
@@ -73,17 +79,11 @@ class ComparisonFailure extends \RuntimeException
$this->message = $message;
}
/**
* @return mixed
*/
public function getActual()
{
return $this->actual;
}
/**
* @return mixed
*/
public function getExpected()
{
return $this->expected;
@@ -114,7 +114,7 @@ class ComparisonFailure extends \RuntimeException
return '';
}
$differ = new Differ("\n--- Expected\n+++ Actual\n");
$differ = new Differ(new UnifiedDiffOutputBuilder("\n--- Expected\n+++ Actual\n"));
return $differ->diff($this->expectedAsString, $this->actualAsString);
}

View File

@@ -1,17 +1,19 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 sprintf;
use function strtolower;
use DOMDocument;
use DOMNode;
use ValueError;
/**
* Compares DOMNode instances for equality.
@@ -21,8 +23,9 @@ class DOMNodeComparator extends ObjectComparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
@@ -42,17 +45,13 @@ class DOMNodeComparator extends ObjectComparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
{
$expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
$actualAsString = $this->nodeToText($actual, true, $ignoreCase);
if ($expectedAsString !== $actualAsString) {
if ($expected instanceof DOMDocument) {
$type = 'documents';
} else {
$type = 'nodes';
}
$type = $expected instanceof DOMDocument ? 'documents' : 'nodes';
throw new ComparisonFailure(
$expected,
@@ -68,40 +67,27 @@ class DOMNodeComparator extends ObjectComparator
/**
* Returns the normalized, whitespace-cleaned, and indented textual
* representation of a DOMNode.
*
* @param DOMNode $node
* @param bool $canonicalize
* @param bool $ignoreCase
* @return string
*/
private function nodeToText(DOMNode $node, $canonicalize, $ignoreCase)
private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase): string
{
if ($canonicalize) {
$document = new DOMDocument;
$document->loadXML($node->C14N());
try {
@$document->loadXML($node->C14N());
} catch (ValueError $e) {
}
$node = $document;
}
if ($node instanceof DOMDocument) {
$document = $node;
} else {
$document = $node->ownerDocument;
}
$document = $node instanceof DOMDocument ? $node : $node->ownerDocument;
$document->formatOutput = true;
$document->normalizeDocument();
if ($node instanceof DOMDocument) {
$text = $node->saveXML();
} else {
$text = $document->saveXML($node);
}
$text = $node instanceof DOMDocument ? $node->saveXML() : $document->saveXML($node);
if ($ignoreCase) {
$text = strtolower($text);
}
return $text;
return $ignoreCase ? strtolower($text) : $text;
}
}

View File

@@ -1,15 +1,23 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 floor;
use function sprintf;
use DateInterval;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use Exception;
/**
* Compares DateTimeInterface instances for equality.
*/
@@ -18,14 +26,15 @@ class DateTimeComparator extends ObjectComparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
{
return ($expected instanceof \DateTime || $expected instanceof \DateTimeInterface) &&
($actual instanceof \DateTime || $actual instanceof \DateTimeInterface);
return ($expected instanceof DateTime || $expected instanceof DateTimeInterface) &&
($actual instanceof DateTime || $actual instanceof DateTimeInterface);
}
/**
@@ -38,17 +47,29 @@ class DateTimeComparator extends ObjectComparator
* @param bool $ignoreCase Case is ignored when set to true
* @param array $processed List of already processed elements (used to prevent infinite recursion)
*
* @throws Exception
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
{
$delta = new \DateInterval(sprintf('PT%sS', abs($delta)));
/** @var DateTimeInterface $expected */
/** @var DateTimeInterface $actual */
$absDelta = abs($delta);
$delta = new DateInterval(sprintf('PT%dS', $absDelta));
$delta->f = $absDelta - floor($absDelta);
$expectedLower = clone $expected;
$expectedUpper = clone $expected;
$actualClone = (clone $actual)
->setTimezone(new DateTimeZone('UTC'));
if ($actual < $expectedLower->sub($delta) ||
$actual > $expectedUpper->add($delta)) {
$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,
@@ -64,14 +85,11 @@ class DateTimeComparator extends ObjectComparator
* Returns an ISO 8601 formatted string representation of a datetime or
* 'Invalid DateTimeInterface object' if the provided DateTimeInterface was not properly
* initialized.
*
* @param \DateTimeInterface $datetime
* @return string
*/
private function dateTimeToString($datetime)
private function dateTimeToString(DateTimeInterface $datetime): string
{
$string = $datetime->format('Y-m-d\TH:i:s.uO');
return $string ? $string : 'Invalid DateTimeInterface object';
return $string ?: 'Invalid DateTimeInterface object';
}
}

View File

@@ -1,17 +1,21 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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_float;
use function is_numeric;
/**
* Compares doubles for equality.
*
* @deprecated since v3.0.5 and v4.0.8
*/
class DoubleComparator extends NumericComparator
{
@@ -20,18 +24,19 @@ class DoubleComparator extends NumericComparator
*
* @var float
*/
const EPSILON = 0.0000000001;
public const EPSILON = 0.0000000001;
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
{
return (is_double($expected) || is_double($actual)) && is_numeric($expected) && is_numeric($actual);
return (is_float($expected) || is_float($actual)) && is_numeric($expected) && is_numeric($actual);
}
/**
@@ -45,7 +50,7 @@ class DoubleComparator extends NumericComparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
{
if ($delta == 0) {
$delta = self::EPSILON;

View File

@@ -1,15 +1,16 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 Exception;
/**
* Compares Exception instances for equality.
*/
@@ -18,20 +19,22 @@ class ExceptionComparator extends ObjectComparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
{
return $expected instanceof \Exception && $actual instanceof \Exception;
return $expected instanceof Exception && $actual instanceof Exception;
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @param object $object
*
* @return array
*/
protected function toArray($object)

View File

@@ -1,48 +1,35 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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;
/**
* Factory for comparators which compare values for equality.
*/
class Factory
{
/**
* @var Comparator[]
*/
private $comparators = array();
/**
* @var Factory
*/
private static $instance;
/**
* Constructs a new factory.
* @var Comparator[]
*/
public function __construct()
{
$this->register(new TypeComparator);
$this->register(new ScalarComparator);
$this->register(new NumericComparator);
$this->register(new DoubleComparator);
$this->register(new ArrayComparator);
$this->register(new ResourceComparator);
$this->register(new ObjectComparator);
$this->register(new ExceptionComparator);
$this->register(new SplObjectStorageComparator);
$this->register(new DOMNodeComparator);
$this->register(new MockObjectComparator);
$this->register(new DateTimeComparator);
}
private $customComparators = [];
/**
* @var Comparator[]
*/
private $defaultComparators = [];
/**
* @return Factory
@@ -50,41 +37,58 @@ class Factory
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self;
self::$instance = new self; // @codeCoverageIgnore
}
return self::$instance;
}
/**
* Constructs a new factory.
*/
public function __construct()
{
$this->registerDefaultComparators();
}
/**
* Returns the correct comparator for comparing two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return Comparator
*/
public function getComparatorFor($expected, $actual)
{
foreach ($this->comparators as $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 getInstance() if its accept() method
* 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 tested
* existing comparators, meaning that its accept() method will be invoked
* before those of the other comparators.
*
* @param Comparator $comparator The registered comparator
* @param Comparator $comparator The comparator to be registered
*/
public function register(Comparator $comparator)
public function register(Comparator $comparator)/*: void*/
{
array_unshift($this->comparators, $comparator);
array_unshift($this->customComparators, $comparator);
$comparator->setFactory($this);
}
@@ -92,16 +96,46 @@ class Factory
/**
* Unregisters a comparator.
*
* This comparator will no longer be returned by getInstance().
* This comparator will no longer be considered by getComparatorFor().
*
* @param Comparator $comparator The unregistered comparator
* @param Comparator $comparator The comparator to be unregistered
*/
public function unregister(Comparator $comparator)
public function unregister(Comparator $comparator)/*: void*/
{
foreach ($this->comparators as $key => $_comparator) {
foreach ($this->customComparators as $key => $_comparator) {
if ($comparator === $_comparator) {
unset($this->comparators[$key]);
unset($this->customComparators[$key]);
}
}
}
/**
* Unregisters all non-default comparators.
*/
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);
}
}

View File

@@ -1,37 +1,40 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 PHPUnit\Framework\MockObject\MockObject;
/**
* Compares PHPUnit_Framework_MockObject_MockObject instances for equality.
* Compares PHPUnit\Framework\MockObject\MockObject instances for equality.
*/
class MockObjectComparator extends ObjectComparator
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
{
return $expected instanceof \PHPUnit_Framework_MockObject_MockObject && $actual instanceof \PHPUnit_Framework_MockObject_MockObject;
return $expected instanceof MockObject && $actual instanceof MockObject;
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @param object $object
*
* @return array
*/
protected function toArray($object)
@@ -42,4 +45,4 @@ class MockObjectComparator extends ObjectComparator
return $array;
}
}
}

View File

@@ -1,15 +1,22 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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;
/**
* Compares numerical values for equality.
*/
@@ -18,16 +25,15 @@ class NumericComparator extends ScalarComparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
{
// all numerical values, but not if one of them is a double
// or both of them are strings
// all numerical values, but not if both of them are strings
return is_numeric($expected) && is_numeric($actual) &&
!(is_double($expected) || is_double($actual)) &&
!(is_string($expected) && is_string($actual));
}
@@ -42,14 +48,14 @@ class NumericComparator extends ScalarComparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
{
if (is_infinite($actual) && is_infinite($expected)) {
if ($this->isInfinite($actual) && $this->isInfinite($expected)) {
return;
}
if ((is_infinite($actual) xor is_infinite($expected)) ||
(is_nan($actual) or is_nan($expected)) ||
if (($this->isInfinite($actual) xor $this->isInfinite($expected)) ||
($this->isNan($actual) || $this->isNan($expected)) ||
abs($actual - $expected) > $delta) {
throw new ComparisonFailure(
$expected,
@@ -65,4 +71,14 @@ class NumericComparator extends ScalarComparator
);
}
}
private function isInfinite($value): bool
{
return is_float($value) && is_infinite($value);
}
private function isNan($value): bool
{
return is_float($value) && is_nan($value);
}
}

View File

@@ -1,15 +1,20 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 get_class;
use function in_array;
use function is_object;
use function sprintf;
use function substr_replace;
/**
* Compares objects for equality.
*/
@@ -18,8 +23,9 @@ class ObjectComparator extends ArrayComparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
@@ -39,7 +45,7 @@ class ObjectComparator extends ArrayComparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
{
if (get_class($actual) !== get_class($expected)) {
throw new ComparisonFailure(
@@ -57,12 +63,12 @@ class ObjectComparator extends ArrayComparator
}
// don't compare twice to allow for cyclic dependencies
if (in_array(array($actual, $expected), $processed, true) ||
in_array(array($expected, $actual), $processed, true)) {
if (in_array([$actual, $expected], $processed, true) ||
in_array([$expected, $actual], $processed, true)) {
return;
}
$processed[] = array($actual, $expected);
$processed[] = [$actual, $expected];
// don't compare objects if they are identical
// this helps to avoid the error "maximum function nesting level reached"
@@ -95,7 +101,8 @@ class ObjectComparator extends ArrayComparator
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @param object $object
*
* @return array
*/
protected function toArray($object)

View File

@@ -1,15 +1,16 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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_resource;
/**
* Compares resources for equality.
*/
@@ -18,8 +19,9 @@ class ResourceComparator extends Comparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
@@ -38,7 +40,7 @@ class ResourceComparator extends Comparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
{
if ($actual != $expected) {
throw new ComparisonFailure(

View File

@@ -1,15 +1,22 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 method_exists;
use function sprintf;
use function strtolower;
/**
* Compares scalar or NULL values for equality.
*/
@@ -18,9 +25,11 @@ class ScalarComparator extends Comparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*
* @since Method available since Release 3.6.0
*/
public function accepts($expected, $actual)
@@ -43,14 +52,14 @@ class ScalarComparator extends Comparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
{
$expectedToCompare = $expected;
$actualToCompare = $actual;
// always compare as strings to avoid strange behaviour
// otherwise 0 == 'Foobar'
if (is_string($expected) || is_string($actual)) {
if ((is_string($expected) && !is_bool($actual)) || (is_string($actual) && !is_bool($expected))) {
$expectedToCompare = (string) $expectedToCompare;
$actualToCompare = (string) $actualToCompare;
@@ -60,18 +69,18 @@ class ScalarComparator extends Comparator
}
}
if ($expectedToCompare != $actualToCompare) {
if (is_string($expected) && is_string($actual)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two strings are equal.'
);
}
if ($expectedToCompare !== $actualToCompare && is_string($expected) && is_string($actual)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two strings are equal.'
);
}
if ($expectedToCompare != $actualToCompare) {
throw new ComparisonFailure(
$expected,
$actual,

View File

@@ -1,15 +1,16 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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 SplObjectStorage;
/**
* Compares \SplObjectStorage instances for equality.
*/
@@ -18,13 +19,14 @@ class SplObjectStorageComparator extends Comparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
{
return $expected instanceof \SplObjectStorage && $actual instanceof \SplObjectStorage;
return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage;
}
/**
@@ -38,7 +40,7 @@ class SplObjectStorageComparator extends Comparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
{
foreach ($actual as $object) {
if (!$expected->contains($object)) {

View File

@@ -1,15 +1,17 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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;
/**
* Compares values for type equality.
*/
@@ -18,8 +20,9 @@ class TypeComparator extends Comparator
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
*
* @return bool
*/
public function accepts($expected, $actual)
@@ -38,7 +41,7 @@ class TypeComparator extends Comparator
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
{
if (gettype($expected) != gettype($actual)) {
throw new ComparisonFailure(

View File

@@ -1,14 +1,16 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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;
class TestClassComparator extends ObjectComparator {
use Throwable;
interface Exception extends Throwable
{
}

View File

@@ -1,14 +1,14 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Comparator package.
* 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;
class TestClass {
final class RuntimeException extends \RuntimeException implements Exception
{
}

View File

@@ -1,163 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ArrayComparator
*
*/
class ArrayComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new ArrayComparator;
$this->comparator->setFactory(new Factory);
}
public function acceptsFailsProvider()
{
return array(
array(array(), null),
array(null, array()),
array(null, null)
);
}
public function assertEqualsSucceedsProvider()
{
return array(
array(
array('a' => 1, 'b' => 2),
array('b' => 2, 'a' => 1)
),
array(
array(1),
array('1')
),
array(
array(3, 2, 1),
array(2, 3, 1),
0,
true
),
array(
array(2.3),
array(2.5),
0.5
),
array(
array(array(2.3)),
array(array(2.5)),
0.5
),
array(
array(new Struct(2.3)),
array(new Struct(2.5)),
0.5
),
);
}
public function assertEqualsFailsProvider()
{
return array(
array(
array(),
array(0 => 1)
),
array(
array(0 => 1),
array()
),
array(
array(0 => null),
array()
),
array(
array(0 => 1, 1 => 2),
array(0 => 1, 1 => 3)
),
array(
array('a', 'b' => array(1, 2)),
array('a', 'b' => array(2, 1))
),
array(
array(2.3),
array(4.2),
0.5
),
array(
array(array(2.3)),
array(array(4.2)),
0.5
),
array(
array(new Struct(2.3)),
array(new Struct(4.2)),
0.5
)
);
}
/**
* @covers ::accepts
*/
public function testAcceptsSucceeds()
{
$this->assertTrue(
$this->comparator->accepts(array(), array())
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0, $canonicalize = false)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual, $delta, $canonicalize);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual,$delta = 0.0, $canonicalize = false)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two arrays are equal'
);
$this->comparator->assertEquals($expected, $actual, $delta, $canonicalize);
}
}

View File

@@ -1,162 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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 DOMNode;
use DOMDocument;
/**
* @coversDefaultClass SebastianBergmann\Comparator\DOMNodeComparator
*
*/
class DOMNodeComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new DOMNodeComparator;
}
public function acceptsSucceedsProvider()
{
$document = new DOMDocument;
$node = new DOMNode;
return array(
array($document, $document),
array($node, $node),
array($document, $node),
array($node, $document)
);
}
public function acceptsFailsProvider()
{
$document = new DOMDocument;
return array(
array($document, null),
array(null, $document),
array(null, null)
);
}
public function assertEqualsSucceedsProvider()
{
return array(
array(
$this->createDOMDocument('<root></root>'),
$this->createDOMDocument('<root/>')
),
array(
$this->createDOMDocument('<root attr="bar"></root>'),
$this->createDOMDocument('<root attr="bar"/>')
),
array(
$this->createDOMDocument('<root><foo attr="bar"></foo></root>'),
$this->createDOMDocument('<root><foo attr="bar"/></root>')
),
array(
$this->createDOMDocument("<root>\n <child/>\n</root>"),
$this->createDOMDocument('<root><child/></root>')
),
);
}
public function assertEqualsFailsProvider()
{
return array(
array(
$this->createDOMDocument('<root></root>'),
$this->createDOMDocument('<bar/>')
),
array(
$this->createDOMDocument('<foo attr1="bar"/>'),
$this->createDOMDocument('<foo attr1="foobar"/>')
),
array(
$this->createDOMDocument('<foo> bar </foo>'),
$this->createDOMDocument('<foo />')
),
array(
$this->createDOMDocument('<foo xmlns="urn:myns:bar"/>'),
$this->createDOMDocument('<foo xmlns="urn:notmyns:bar"/>')
),
array(
$this->createDOMDocument('<foo> bar </foo>'),
$this->createDOMDocument('<foo> bir </foo>')
)
);
}
private function createDOMDocument($content)
{
$document = new DOMDocument;
$document->preserveWhiteSpace = false;
$document->loadXML($content);
return $document;
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two DOM'
);
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -1,216 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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 DateTime;
use DateTimeImmutable;
use DateTimeZone;
/**
* @coversDefaultClass SebastianBergmann\Comparator\DateTimeComparator
*
*/
class DateTimeComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new DateTimeComparator;
}
public function acceptsFailsProvider()
{
$datetime = new DateTime;
return array(
array($datetime, null),
array(null, $datetime),
array(null, null)
);
}
public function assertEqualsSucceedsProvider()
{
return array(
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York'))
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 04:13:25', new DateTimeZone('America/New_York')),
10
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 04:14:40', new DateTimeZone('America/New_York')),
65
),
array(
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29', new DateTimeZone('America/New_York'))
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago'))
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 03:13:49', new DateTimeZone('America/Chicago')),
15
),
array(
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
),
array(
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 23:01:30', new DateTimeZone('America/Chicago')),
100
),
array(
new DateTime('@1364616000'),
new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
),
array(
new DateTime('2013-03-29T05:13:35-0500'),
new DateTime('2013-03-29T04:13:35-0600')
)
);
}
public function assertEqualsFailsProvider()
{
return array(
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York'))
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')),
3500
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 05:13:35', new DateTimeZone('America/New_York')),
3500
),
array(
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
new DateTime('2013-03-30', new DateTimeZone('America/New_York'))
),
array(
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
43200
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
),
array(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
3500
),
array(
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
new DateTime('2013-03-30', new DateTimeZone('America/Chicago'))
),
array(
new DateTime('2013-03-29T05:13:35-0600'),
new DateTime('2013-03-29T04:13:35-0600')
),
array(
new DateTime('2013-03-29T05:13:35-0600'),
new DateTime('2013-03-29T05:13:35-0500')
),
);
}
/**
* @covers ::accepts
*/
public function testAcceptsSucceeds()
{
$this->assertTrue(
$this->comparator->accepts(
new DateTime,
new DateTime
)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two DateTime objects are equal.'
);
$this->comparator->assertEquals($expected, $actual, $delta);
}
/**
* @requires PHP 5.5
* @covers ::accepts
*/
public function testAcceptsDateTimeInterface()
{
$this->assertTrue($this->comparator->accepts(new DateTime, new DateTimeImmutable));
}
/**
* @requires PHP 5.5
* @covers ::assertEquals
*/
public function testSupportsDateTimeInterface()
{
$this->comparator->assertEquals(
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
new DateTimeImmutable('2013-03-29 04:13:35', new DateTimeZone('America/New_York'))
);
}
}

View File

@@ -1,134 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* @coversDefaultClass SebastianBergmann\Comparator\DoubleComparator
*
*/
class DoubleComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new DoubleComparator;
}
public function acceptsSucceedsProvider()
{
return array(
array(0, 5.0),
array(5.0, 0),
array('5', 4.5),
array(1.2e3, 7E-10),
array(3, acos(8)),
array(acos(8), 3),
array(acos(8), acos(8))
);
}
public function acceptsFailsProvider()
{
return array(
array(5, 5),
array('4.5', 5),
array(0x539, 02471),
array(5.0, false),
array(null, 5.0)
);
}
public function assertEqualsSucceedsProvider()
{
return array(
array(2.3, 2.3),
array('2.3', 2.3),
array(5.0, 5),
array(5, 5.0),
array(5.0, '5'),
array(1.2e3, 1200),
array(2.3, 2.5, 0.5),
array(3, 3.05, 0.05),
array(1.2e3, 1201, 1),
array((string)(1/3), 1 - 2/3),
array(1/3, (string)(1 - 2/3))
);
}
public function assertEqualsFailsProvider()
{
return array(
array(2.3, 4.2),
array('2.3', 4.2),
array(5.0, '4'),
array(5.0, 6),
array(1.2e3, 1201),
array(2.3, 2.5, 0.2),
array(3, 3.05, 0.04),
array(3, acos(8)),
array(acos(8), 3),
array(acos(8), acos(8))
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', 'matches expected'
);
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -1,136 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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 \Exception;
use \RuntimeException;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ExceptionComparator
*
*/
class ExceptionComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new ExceptionComparator;
$this->comparator->setFactory(new Factory);
}
public function acceptsSucceedsProvider()
{
return array(
array(new Exception, new Exception),
array(new RuntimeException, new RuntimeException),
array(new Exception, new RuntimeException)
);
}
public function acceptsFailsProvider()
{
return array(
array(new Exception, null),
array(null, new Exception),
array(null, null)
);
}
public function assertEqualsSucceedsProvider()
{
$exception1 = new Exception;
$exception2 = new Exception;
$exception3 = new RunTimeException('Error', 100);
$exception4 = new RunTimeException('Error', 100);
return array(
array($exception1, $exception1),
array($exception1, $exception2),
array($exception3, $exception3),
array($exception3, $exception4)
);
}
public function assertEqualsFailsProvider()
{
$typeMessage = 'not instance of expected class';
$equalMessage = 'Failed asserting that two objects are equal.';
$exception1 = new Exception('Error', 100);
$exception2 = new Exception('Error', 101);
$exception3 = new Exception('Errors', 101);
$exception4 = new RunTimeException('Error', 100);
$exception5 = new RunTimeException('Error', 101);
return array(
array($exception1, $exception2, $equalMessage),
array($exception1, $exception3, $equalMessage),
array($exception1, $exception4, $typeMessage),
array($exception2, $exception3, $equalMessage),
array($exception4, $exception5, $equalMessage)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual, $message)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -1,115 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* @coversDefaultClass SebastianBergmann\Comparator\Factory
*
*/
class FactoryTest extends \PHPUnit_Framework_TestCase
{
public function instanceProvider()
{
$tmpfile = tmpfile();
return array(
array(NULL, NULL, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array(NULL, TRUE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array(TRUE, NULL, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array(TRUE, TRUE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array(FALSE, FALSE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array(TRUE, FALSE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array(FALSE, TRUE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array('', '', 'SebastianBergmann\\Comparator\\ScalarComparator'),
array('0', '0', 'SebastianBergmann\\Comparator\\ScalarComparator'),
array('0', 0, 'SebastianBergmann\\Comparator\\NumericComparator'),
array(0, '0', 'SebastianBergmann\\Comparator\\NumericComparator'),
array(0, 0, 'SebastianBergmann\\Comparator\\NumericComparator'),
array(1.0, 0, 'SebastianBergmann\\Comparator\\DoubleComparator'),
array(0, 1.0, 'SebastianBergmann\\Comparator\\DoubleComparator'),
array(1.0, 1.0, 'SebastianBergmann\\Comparator\\DoubleComparator'),
array(array(1), array(1), 'SebastianBergmann\\Comparator\\ArrayComparator'),
array($tmpfile, $tmpfile, 'SebastianBergmann\\Comparator\\ResourceComparator'),
array(new \stdClass, new \stdClass, 'SebastianBergmann\\Comparator\\ObjectComparator'),
array(new \DateTime, new \DateTime, 'SebastianBergmann\\Comparator\\DateTimeComparator'),
array(new \SplObjectStorage, new \SplObjectStorage, 'SebastianBergmann\\Comparator\\SplObjectStorageComparator'),
array(new \Exception, new \Exception, 'SebastianBergmann\\Comparator\\ExceptionComparator'),
array(new \DOMDocument, new \DOMDocument, 'SebastianBergmann\\Comparator\\DOMNodeComparator'),
// mixed types
array($tmpfile, array(1), 'SebastianBergmann\\Comparator\\TypeComparator'),
array(array(1), $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'),
array($tmpfile, '1', 'SebastianBergmann\\Comparator\\TypeComparator'),
array('1', $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'),
array($tmpfile, new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
array(new \stdClass, $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'),
array(new \stdClass, array(1), 'SebastianBergmann\\Comparator\\TypeComparator'),
array(array(1), new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
array(new \stdClass, '1', 'SebastianBergmann\\Comparator\\TypeComparator'),
array('1', new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
array(new ClassWithToString, '1', 'SebastianBergmann\\Comparator\\ScalarComparator'),
array('1', new ClassWithToString, 'SebastianBergmann\\Comparator\\ScalarComparator'),
array(1.0, new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
array(new \stdClass, 1.0, 'SebastianBergmann\\Comparator\\TypeComparator'),
array(1.0, array(1), 'SebastianBergmann\\Comparator\\TypeComparator'),
array(array(1), 1.0, 'SebastianBergmann\\Comparator\\TypeComparator'),
);
}
/**
* @dataProvider instanceProvider
* @covers ::getComparatorFor
* @covers ::__construct
*/
public function testGetComparatorFor($a, $b, $expected)
{
$factory = new Factory;
$actual = $factory->getComparatorFor($a, $b);
$this->assertInstanceOf($expected, $actual);
}
/**
* @covers ::register
*/
public function testRegister()
{
$comparator = new TestClassComparator;
$factory = new Factory;
$factory->register($comparator);
$a = new TestClass;
$b = new TestClass;
$expected = 'SebastianBergmann\\Comparator\\TestClassComparator';
$actual = $factory->getComparatorFor($a, $b);
$factory->unregister($comparator);
$this->assertInstanceOf($expected, $actual);
}
/**
* @covers ::unregister
*/
public function testUnregister()
{
$comparator = new TestClassComparator;
$factory = new Factory;
$factory->register($comparator);
$factory->unregister($comparator);
$a = new TestClass;
$b = new TestClass;
$expected = 'SebastianBergmann\\Comparator\\ObjectComparator';
$actual = $factory->getComparatorFor($a, $b);
$this->assertInstanceOf($expected, $actual);
}
}

View File

@@ -1,166 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* @coversDefaultClass SebastianBergmann\Comparator\MockObjectComparator
*
*/
class MockObjectComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new MockObjectComparator;
$this->comparator->setFactory(new Factory);
}
public function acceptsSucceedsProvider()
{
$testmock = $this->getMock('SebastianBergmann\\Comparator\\TestClass');
$stdmock = $this->getMock('stdClass');
return array(
array($testmock, $testmock),
array($stdmock, $stdmock),
array($stdmock, $testmock)
);
}
public function acceptsFailsProvider()
{
$stdmock = $this->getMock('stdClass');
return array(
array($stdmock, null),
array(null, $stdmock),
array(null, null)
);
}
public function assertEqualsSucceedsProvider()
{
// cyclic dependencies
$book1 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book1->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratchett'));
$book1->author->books[] = $book1;
$book2 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book2->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratchett'));
$book2->author->books[] = $book2;
$object1 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15));
$object2 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15));
return array(
array($object1, $object1),
array($object1, $object2),
array($book1, $book1),
array($book1, $book2),
array(
$this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(2.3)),
$this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(2.5)),
0.5
)
);
}
public function assertEqualsFailsProvider()
{
$typeMessage = 'is not instance of expected class';
$equalMessage = 'Failed asserting that two objects are equal.';
// cyclic dependencies
$book1 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book1->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratchett'));
$book1->author->books[] = $book1;
$book2 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book2->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratch'));
$book2->author->books[] = $book2;
$book3 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book3->author = 'Terry Pratchett';
$book4 = $this->getMock('stdClass');
$book4->author = 'Terry Pratchett';
$object1 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15));
$object2 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(16, 23, 42));
return array(
array(
$this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15)),
$this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(16, 23, 42)),
$equalMessage
),
array($object1, $object2, $equalMessage),
array($book1, $book2, $equalMessage),
array($book3, $book4, $typeMessage),
array(
$this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(2.3)),
$this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(4.2)),
$equalMessage,
0.5
)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual, $message, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -1,122 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* @coversDefaultClass SebastianBergmann\Comparator\NumericComparator
*
*/
class NumericComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new NumericComparator;
}
public function acceptsSucceedsProvider()
{
return array(
array(5, 10),
array(8, '0'),
array('10', 0),
array(0x74c3b00c, 42),
array(0755, 0777)
);
}
public function acceptsFailsProvider()
{
return array(
array('5', '10'),
array(8, 5.0),
array(5.0, 8),
array(10, null),
array(false, 12)
);
}
public function assertEqualsSucceedsProvider()
{
return array(
array(1337, 1337),
array('1337', 1337),
array(0x539, 1337),
array(02471, 1337),
array(1337, 1338, 1),
array('1337', 1340, 5),
);
}
public function assertEqualsFailsProvider()
{
return array(
array(1337, 1338),
array('1338', 1337),
array(0x539, 1338),
array(1337, 1339, 1),
array('1337', 1340, 2),
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', 'matches expected'
);
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -1,150 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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 stdClass;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ObjectComparator
*
*/
class ObjectComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new ObjectComparator;
$this->comparator->setFactory(new Factory);
}
public function acceptsSucceedsProvider()
{
return array(
array(new TestClass, new TestClass),
array(new stdClass, new stdClass),
array(new stdClass, new TestClass)
);
}
public function acceptsFailsProvider()
{
return array(
array(new stdClass, null),
array(null, new stdClass),
array(null, null)
);
}
public function assertEqualsSucceedsProvider()
{
// cyclic dependencies
$book1 = new Book;
$book1->author = new Author('Terry Pratchett');
$book1->author->books[] = $book1;
$book2 = new Book;
$book2->author = new Author('Terry Pratchett');
$book2->author->books[] = $book2;
$object1 = new SampleClass(4, 8, 15);
$object2 = new SampleClass(4, 8, 15);
return array(
array($object1, $object1),
array($object1, $object2),
array($book1, $book1),
array($book1, $book2),
array(new Struct(2.3), new Struct(2.5), 0.5)
);
}
public function assertEqualsFailsProvider()
{
$typeMessage = 'is not instance of expected class';
$equalMessage = 'Failed asserting that two objects are equal.';
// cyclic dependencies
$book1 = new Book;
$book1->author = new Author('Terry Pratchett');
$book1->author->books[] = $book1;
$book2 = new Book;
$book2->author = new Author('Terry Pratch');
$book2->author->books[] = $book2;
$book3 = new Book;
$book3->author = 'Terry Pratchett';
$book4 = new stdClass;
$book4->author = 'Terry Pratchett';
$object1 = new SampleClass( 4, 8, 15);
$object2 = new SampleClass(16, 23, 42);
return array(
array(new SampleClass(4, 8, 15), new SampleClass(16, 23, 42), $equalMessage),
array($object1, $object2, $equalMessage),
array($book1, $book2, $equalMessage),
array($book3, $book4, $typeMessage),
array(new Struct(2.3), new Struct(4.2), $equalMessage, 0.5)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual, $message, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -1,120 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ResourceComparator
*
*/
class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new ResourceComparator;
}
public function acceptsSucceedsProvider()
{
$tmpfile1 = tmpfile();
$tmpfile2 = tmpfile();
return array(
array($tmpfile1, $tmpfile1),
array($tmpfile2, $tmpfile2),
array($tmpfile1, $tmpfile2)
);
}
public function acceptsFailsProvider()
{
$tmpfile1 = tmpfile();
return array(
array($tmpfile1, null),
array(null, $tmpfile1),
array(null, null)
);
}
public function assertEqualsSucceedsProvider()
{
$tmpfile1 = tmpfile();
$tmpfile2 = tmpfile();
return array(
array($tmpfile1, $tmpfile1),
array($tmpfile2, $tmpfile2)
);
}
public function assertEqualsFailsProvider()
{
$tmpfile1 = tmpfile();
$tmpfile2 = tmpfile();
return array(
array($tmpfile1, $tmpfile2),
array($tmpfile2, $tmpfile1)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException('SebastianBergmann\\Comparator\\ComparisonFailure');
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -1,158 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ScalarComparator
*
*/
class ScalarComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new ScalarComparator;
}
public function acceptsSucceedsProvider()
{
return array(
array("string", "string"),
array(new ClassWithToString, "string"),
array("string", new ClassWithToString),
array("string", null),
array(false, "string"),
array(false, true),
array(null, false),
array(null, null),
array("10", 10),
array("", false),
array("1", true),
array(1, true),
array(0, false),
array(0.1, "0.1")
);
}
public function acceptsFailsProvider()
{
return array(
array(array(), array()),
array("string", array()),
array(new ClassWithToString, new ClassWithToString),
array(false, new ClassWithToString),
array(tmpfile(), tmpfile())
);
}
public function assertEqualsSucceedsProvider()
{
return array(
array("string", "string"),
array(new ClassWithToString, new ClassWithToString),
array("string representation", new ClassWithToString),
array(new ClassWithToString, "string representation"),
array("string", "STRING", true),
array("STRING", "string", true),
array("String Representation", new ClassWithToString, true),
array(new ClassWithToString, "String Representation", true),
array("10", 10),
array("", false),
array("1", true),
array(1, true),
array(0, false),
array(0.1, "0.1"),
array(false, null),
array(false, false),
array(true, true),
array(null, null)
);
}
public function assertEqualsFailsProvider()
{
$stringException = 'Failed asserting that two strings are equal.';
$otherException = 'matches expected';
return array(
array("string", "other string", $stringException),
array("string", "STRING", $stringException),
array("STRING", "string", $stringException),
array("string", "other string", $stringException),
// https://github.com/sebastianbergmann/phpunit/issues/1023
array('9E6666666','9E7777777', $stringException),
array(new ClassWithToString, "does not match", $otherException),
array("does not match", new ClassWithToString, $otherException),
array(0, 'Foobar', $otherException),
array('Foobar', 0, $otherException),
array("10", 25, $otherException),
array("1", false, $otherException),
array("", true, $otherException),
array(false, true, $otherException),
array(true, false, $otherException),
array(null, true, $otherException),
array(0, true, $otherException)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual, $ignoreCase = false)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual, 0.0, false, $ignoreCase);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual, $message)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -1,137 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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 SplObjectStorage;
use stdClass;
/**
* @coversDefaultClass SebastianBergmann\Comparator\SplObjectStorageComparator
*
*/
class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new SplObjectStorageComparator;
}
public function acceptsFailsProvider()
{
return array(
array(new SplObjectStorage, new stdClass),
array(new stdClass, new SplObjectStorage),
array(new stdClass, new stdClass)
);
}
public function assertEqualsSucceedsProvider()
{
$object1 = new stdClass();
$object2 = new stdClass();
$storage1 = new SplObjectStorage();
$storage2 = new SplObjectStorage();
$storage3 = new SplObjectStorage();
$storage3->attach($object1);
$storage3->attach($object2);
$storage4 = new SplObjectStorage();
$storage4->attach($object2);
$storage4->attach($object1);
return array(
array($storage1, $storage1),
array($storage1, $storage2),
array($storage3, $storage3),
array($storage3, $storage4)
);
}
public function assertEqualsFailsProvider()
{
$object1 = new stdClass;
$object2 = new stdClass;
$storage1 = new SplObjectStorage;
$storage2 = new SplObjectStorage;
$storage2->attach($object1);
$storage3 = new SplObjectStorage;
$storage3->attach($object2);
$storage3->attach($object1);
return array(
array($storage1, $storage2),
array($storage1, $storage3),
array($storage2, $storage3),
);
}
/**
* @covers ::accepts
*/
public function testAcceptsSucceeds()
{
$this->assertTrue(
$this->comparator->accepts(
new SplObjectStorage,
new SplObjectStorage
)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsFailsProvider
*/
public function testAcceptsFails($expected, $actual)
{
$this->assertFalse(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two objects are equal.'
);
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -1,104 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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 stdClass;
/**
* @coversDefaultClass SebastianBergmann\Comparator\TypeComparator
*
*/
class TypeComparatorTest extends \PHPUnit_Framework_TestCase
{
private $comparator;
protected function setUp()
{
$this->comparator = new TypeComparator;
}
public function acceptsSucceedsProvider()
{
return array(
array(true, 1),
array(false, array(1)),
array(null, new stdClass),
array(1.0, 5),
array("", "")
);
}
public function assertEqualsSucceedsProvider()
{
return array(
array(true, true),
array(true, false),
array(false, false),
array(null, null),
array(new stdClass, new stdClass),
array(0, 0),
array(1.0, 2.0),
array("hello", "world"),
array("", ""),
array(array(), array(1,2,3))
);
}
public function assertEqualsFailsProvider()
{
return array(
array(true, null),
array(null, false),
array(1.0, 0),
array(new stdClass, array()),
array("1", 1)
);
}
/**
* @covers ::accepts
* @dataProvider acceptsSucceedsProvider
*/
public function testAcceptsSucceeds($expected, $actual)
{
$this->assertTrue(
$this->comparator->accepts($expected, $actual)
);
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsSucceedsProvider
*/
public function testAssertEqualsSucceeds($expected, $actual)
{
$exception = null;
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
}
/**
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException('SebastianBergmann\\Comparator\\ComparisonFailure', 'does not match expected type');
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -1,28 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* An author.
*
*/
class Author
{
// the order of properties is important for testing the cycle!
public $books = array();
private $name = '';
public function __construct($name)
{
$this->name = $name;
}
}

View File

@@ -1,21 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* A book.
*
*/
class Book
{
// the order of properties is important for testing the cycle!
public $author = null;
}

View File

@@ -1,19 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
class ClassWithToString
{
public function __toString()
{
return 'string representation';
}
}

View File

@@ -1,29 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* A sample class.
*
*/
class SampleClass
{
public $a;
protected $b;
protected $c;
public function __construct($a, $b, $c)
{
$this->a = $a;
$this->b = $b;
$this->c = $c;
}
}

View File

@@ -1,25 +0,0 @@
<?php
/*
* This file is part of the Comparator package.
*
* (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;
/**
* A struct.
*
*/
class Struct
{
public $var;
public function __construct($var)
{
$this->var = $var;
}
}

View File

@@ -1,38 +0,0 @@
<?php
// @codingStandardsIgnoreFile
// @codeCoverageIgnoreStart
// this is an autogenerated file - do not edit
spl_autoload_register(
function($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
'sebastianbergmann\\comparator\\arraycomparatortest' => '/ArrayComparatorTest.php',
'sebastianbergmann\\comparator\\author' => '/_files/Author.php',
'sebastianbergmann\\comparator\\book' => '/_files/Book.php',
'sebastianbergmann\\comparator\\classwithtostring' => '/_files/ClassWithToString.php',
'sebastianbergmann\\comparator\\datetimecomparatortest' => '/DateTimeComparatorTest.php',
'sebastianbergmann\\comparator\\domnodecomparatortest' => '/DOMNodeComparatorTest.php',
'sebastianbergmann\\comparator\\doublecomparatortest' => '/DoubleComparatorTest.php',
'sebastianbergmann\\comparator\\exceptioncomparatortest' => '/ExceptionComparatorTest.php',
'sebastianbergmann\\comparator\\factorytest' => '/FactoryTest.php',
'sebastianbergmann\\comparator\\mockobjectcomparatortest' => '/MockObjectComparatorTest.php',
'sebastianbergmann\\comparator\\numericcomparatortest' => '/NumericComparatorTest.php',
'sebastianbergmann\\comparator\\objectcomparatortest' => '/ObjectComparatorTest.php',
'sebastianbergmann\\comparator\\resourcecomparatortest' => '/ResourceComparatorTest.php',
'sebastianbergmann\\comparator\\sampleclass' => '/_files/SampleClass.php',
'sebastianbergmann\\comparator\\scalarcomparatortest' => '/ScalarComparatorTest.php',
'sebastianbergmann\\comparator\\splobjectstoragecomparatortest' => '/SplObjectStorageComparatorTest.php',
'sebastianbergmann\\comparator\\struct' => '/_files/Struct.php',
'sebastianbergmann\\comparator\\testclass' => '/_files/TestClass.php',
'sebastianbergmann\\comparator\\testclasscomparator' => '/_files/TestClassComparator.php',
'sebastianbergmann\\comparator\\typecomparatortest' => '/TypeComparatorTest.php'
);
}
$cn = strtolower($class);
if (isset($classes[$cn])) {
require __DIR__ . $classes[$cn];
}
}
);
// @codeCoverageIgnoreEnd

View File

@@ -1,7 +0,0 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/autoload.php';
ini_set('precision', 14);
ini_set('serialize_precision', 14);

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"/>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<psalm
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
resolveFromConfigFile="false"
errorBaseline=".psalm/baseline.xml"
totallyTyped="true"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

View File

@@ -0,0 +1,30 @@
# ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
## [2.0.2] - 2020-10-26
### Fixed
* `SebastianBergmann\Complexity\Exception` now correctly extends `\Throwable`
## [2.0.1] - 2020-09-28
### Changed
* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
## [2.0.0] - 2020-07-25
### Removed
* The `ParentConnectingVisitor` has been removed (it should have been marked as `@internal`)
## [1.0.0] - 2020-07-22
* Initial release
[2.0.2]: https://github.com/sebastianbergmann/complexity/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/sebastianbergmann/complexity/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/sebastianbergmann/complexity/compare/1.0.0...2.0.0
[1.0.0]: https://github.com/sebastianbergmann/complexity/compare/70ee0ad32d9e2be3f85beffa3e2eb474193f2487...1.0.0

33
vendor/sebastian/complexity/LICENSE vendored Normal file
View File

@@ -0,0 +1,33 @@
sebastian/complexity
Copyright (c) 2020, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Sebastian Bergmann nor the names of his
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 OWNER 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.

22
vendor/sebastian/complexity/README.md vendored Normal file
View File

@@ -0,0 +1,22 @@
# sebastian/complexity
Library for calculating the complexity of PHP code units.
[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/complexity.svg?style=flat-square)](https://packagist.org/packages/sebastian/complexity)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.3-8892BF.svg?style=flat-square)](https://php.net/)
[![CI Status](https://github.com/sebastianbergmann/complexity/workflows/CI/badge.svg?branch=master&event=push)](https://phpunit.de/build-status.html)
[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/complexity/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/complexity)
## Installation
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
```
composer require sebastian/complexity
```
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/complexity
```

View File

@@ -0,0 +1,41 @@
{
"name": "sebastian/complexity",
"description": "Library for calculating the complexity of PHP code units",
"type": "library",
"homepage": "https://github.com/sebastianbergmann/complexity",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/complexity/issues"
},
"require": {
"php": ">=7.3",
"nikic/php-parser": "^4.7"
},
"require-dev": {
"phpunit/phpunit": "^9.3"
},
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
}
}

View File

@@ -0,0 +1,88 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/complexity.
*
* (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\Complexity;
use PhpParser\Error;
use PhpParser\Lexer;
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\NameResolver;
use PhpParser\NodeVisitor\ParentConnectingVisitor;
use PhpParser\Parser;
use PhpParser\ParserFactory;
final class Calculator
{
/**
* @throws RuntimeException
*/
public function calculateForSourceFile(string $sourceFile): ComplexityCollection
{
return $this->calculateForSourceString(file_get_contents($sourceFile));
}
/**
* @throws RuntimeException
*/
public function calculateForSourceString(string $source): ComplexityCollection
{
try {
$nodes = $this->parser()->parse($source);
assert($nodes !== null);
return $this->calculateForAbstractSyntaxTree($nodes);
// @codeCoverageIgnoreStart
} catch (Error $error) {
throw new RuntimeException(
$error->getMessage(),
(int) $error->getCode(),
$error
);
}
// @codeCoverageIgnoreEnd
}
/**
* @param Node[] $nodes
*
* @throws RuntimeException
*/
public function calculateForAbstractSyntaxTree(array $nodes): ComplexityCollection
{
$traverser = new NodeTraverser;
$complexityCalculatingVisitor = new ComplexityCalculatingVisitor(true);
$traverser->addVisitor(new NameResolver);
$traverser->addVisitor(new ParentConnectingVisitor);
$traverser->addVisitor($complexityCalculatingVisitor);
try {
/* @noinspection UnusedFunctionResultInspection */
$traverser->traverse($nodes);
// @codeCoverageIgnoreStart
} catch (Error $error) {
throw new RuntimeException(
$error->getMessage(),
(int) $error->getCode(),
$error
);
}
// @codeCoverageIgnoreEnd
return $complexityCalculatingVisitor->result();
}
private function parser(): Parser
{
return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
}
}

View File

@@ -0,0 +1,42 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/complexity.
*
* (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\Complexity;
/**
* @psalm-immutable
*/
final class Complexity
{
/**
* @var string
*/
private $name;
/**
* @var int
*/
private $cyclomaticComplexity;
public function __construct(string $name, int $cyclomaticComplexity)
{
$this->name = $name;
$this->cyclomaticComplexity = $cyclomaticComplexity;
}
public function name(): string
{
return $this->name;
}
public function cyclomaticComplexity(): int
{
return $this->cyclomaticComplexity;
}
}

View File

@@ -0,0 +1,72 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/complexity.
*
* (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\Complexity;
use function count;
use Countable;
use IteratorAggregate;
/**
* @psalm-immutable
*/
final class ComplexityCollection implements Countable, IteratorAggregate
{
/**
* @psalm-var list<Complexity>
*/
private $items = [];
public static function fromList(Complexity ...$items): self
{
return new self($items);
}
/**
* @psalm-param list<Complexity> $items
*/
private function __construct(array $items)
{
$this->items = $items;
}
/**
* @psalm-return list<Complexity>
*/
public function asArray(): array
{
return $this->items;
}
public function getIterator(): ComplexityCollectionIterator
{
return new ComplexityCollectionIterator($this);
}
public function count(): int
{
return count($this->items);
}
public function isEmpty(): bool
{
return empty($this->items);
}
public function cyclomaticComplexity(): int
{
$cyclomaticComplexity = 0;
foreach ($this as $item) {
$cyclomaticComplexity += $item->cyclomaticComplexity();
}
return $cyclomaticComplexity;
}
}

View File

@@ -0,0 +1,55 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/complexity.
*
* (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\Complexity;
use Iterator;
final class ComplexityCollectionIterator implements Iterator
{
/**
* @psalm-var list<Complexity>
*/
private $items;
/**
* @var int
*/
private $position = 0;
public function __construct(ComplexityCollection $items)
{
$this->items = $items->asArray();
}
public function rewind(): void
{
$this->position = 0;
}
public function valid(): bool
{
return isset($this->items[$this->position]);
}
public function key(): int
{
return $this->position;
}
public function current(): Complexity
{
return $this->items[$this->position];
}
public function next(): void
{
$this->position++;
}
}

View File

@@ -1,18 +1,16 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the GlobalState package.
* This file is part of sebastian/complexity.
*
* (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\Complexity;
namespace SebastianBergmann\GlobalState\TestFixture;
use Throwable;
/**
*/
class BlacklistedClass
interface Exception extends Throwable
{
private static $attribute;
}

Some files were not shown because too many files have changed in this diff Show More