Add pear modules, mail and net_smtp via composer (#93)

Add pear modules, mail and net_smtp via composer, remove php 5.6 build due to phpunit 6
This commit is contained in:
Thilina Hasantha
2018-01-08 23:13:43 +01:00
committed by GitHub
parent 359e3f8382
commit e7792e7d79
2349 changed files with 117270 additions and 83170 deletions

View File

@@ -1,8 +1,4 @@
.idea
composer.lock
composer.phar
vendor/
cache.properties
build/LICENSE
build/README.md
build/*.tgz
/.idea
/composer.lock
/vendor

View File

@@ -3,14 +3,23 @@ language: php
php:
- 5.6
- 7.0
- 7.0snapshot
- 7.1
- 7.1snapshot
- master
sudo: false
before_script:
before_install:
- composer self-update
- composer install --no-interaction --prefer-source --dev
- composer clear-cache
script: ./vendor/bin/phpunit
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

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

View File

@@ -4,10 +4,11 @@ Looks up which function or method a line of code belongs to.
## Installation
To add this component as a local, per-project dependency to your project, simply add a dependency on `sebastian/code-unit-reverse-lookup` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on version 1.0 of this component:
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
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
{
"require": {
"sebastian/code-unit-reverse-lookup": "~1.0"
}
}

View File

@@ -1,26 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="code-unit-reverse-lookup">
<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">
<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 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

@@ -10,10 +10,10 @@
}
],
"require": {
"php": ">=5.6"
"php": "^5.6 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "~5"
"phpunit/phpunit": "^5.7 || ^6.0"
},
"autoload": {
"classmap": [

View File

@@ -10,10 +10,12 @@
namespace SebastianBergmann\CodeUnitReverseLookup;
use PHPUnit\Framework\TestCase;
/**
* @covers SebastianBergmann\CodeUnitReverseLookup\Wizard
*/
class WizardTest extends \PHPUnit_Framework_TestCase
class WizardTest extends TestCase
{
/**
* @var Wizard

View File

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

View File

@@ -0,0 +1,81 @@
<?php
$header = <<<'EOF'
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.
EOF;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(
[
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true
],
'blank_line_after_namespace' => true,
'blank_line_before_return' => true,
'braces' => true,
'cast_spaces' => true,
'concat_space' => ['spacing' => 'one'],
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'function_declaration' => true,
'header_comment' => ['header' => $header, 'separate' => 'none'],
'indentation_type' => true,
'line_ending' => true,
'lowercase_constants' => true,
'lowercase_keywords' => true,
'method_argument_space' => true,
//'native_function_invocation' => true,
'no_alias_functions' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_closing_tag' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_consecutive_blank_lines' => true,
'no_leading_namespace_whitespace' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_inside_parenthesis' => true,
'no_trailing_comma_in_list_call' => true,
'no_trailing_whitespace' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'phpdoc_align' => true,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_scalar' => true,
//'phpdoc_separation' => true,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'self_accessor' => true,
'simplified_null_return' => true,
'single_blank_line_at_eof' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_quote' => true,
'strict_param' => true,
'ternary_operator_spaces' => true,
'trim_array_spaces' => true,
'visibility_required' => true,
]
)
->setFinder(
PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests')
->exclude(__DIR__.'/tests/_fixture')
->name('*.php')
);

View File

@@ -2,24 +2,33 @@ 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
- 7.0
- 7.1
- 7.2
- master
env:
matrix:
- DEPENDENCIES="high"
- DEPENDENCIES="low"
global:
- DEFAULT_COMPOSER_FLAGS="--no-interaction --no-ansi --no-progress --no-suggest"
before_install:
- composer self-update
- composer clear-cache
install:
- if [[ "$DEPENDENCIES" = 'high' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS; fi
- if [[ "$DEPENDENCIES" = 'low' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS --prefer-lowest; fi
script:
- ./vendor/bin/phpunit --coverage-clover=coverage.xml
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
email: false
webhooks:
urls:
- https://webhooks.gitter.im/e/6668f52f3dd4e3f81960
on_success: always
on_failure: always
on_start: false

View File

@@ -0,0 +1,19 @@
# ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [2.1.1] - 2017-12-22
### Fixed
* 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`
[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-2017, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -30,9 +30,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 +1,21 @@
<?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>
<project name="comparator" default="setup">
<target name="setup" depends="clean,composer"/>
<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>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/vendor"/>
<delete file="${basedir}/composer.lock"/>
</target>
<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>
<target name="composer" depends="clean" description="Install dependencies with Composer">
<exec executable="composer" taskname="composer">
<env key="COMPOSER_DISABLE_XDEBUG_WARN" value="1"/>
<arg value="update"/>
<arg value="--no-interaction"/>
<arg value="--no-progress"/>
<arg value="--no-ansi"/>
<arg value="--no-suggest"/>
</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,32 @@
"email": "bschussek@2bepublished.at"
}
],
"prefer-stable": true,
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.2",
"sebastian/exporter": "~1.2 || ~2.0"
"php": "^7.0",
"sebastian/diff": "^2.0",
"sebastian/exporter": "^3.1"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
"phpunit/phpunit": "^6.4"
},
"config": {
"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": "2.1.x-dev"
}
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.0/phpunit.xsd"
bootstrap="vendor/autoload.php"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="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,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

@@ -18,8 +18,9 @@ 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)
@@ -30,35 +31,32 @@ class ArrayComparator extends Comparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @param array $processed
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
* @param array $processed List of already processed elements (used to prevent infinite recursion)
*
* @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 = [])
{
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)
@@ -73,31 +71,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;
@@ -105,7 +100,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)
@@ -114,15 +109,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

@@ -43,8 +43,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);
@@ -52,17 +53,13 @@ abstract class Comparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
*
* @throws ComparisonFailure
*/
abstract public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false);
}

View File

@@ -11,6 +11,7 @@
namespace SebastianBergmann\Comparator;
use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
/**
* Thrown when an assertion for string equality failed.
@@ -19,24 +20,28 @@ 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
*
* @var string
*/
protected $expectedAsString;
/**
* 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;
@@ -114,7 +120,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

@@ -21,8 +21,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)
@@ -33,29 +34,22 @@ class DOMNodeComparator extends ObjectComparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
* @param array $processed List of already processed elements (used to prevent infinite recursion)
*
* @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, array &$processed = [])
{
$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,
@@ -71,40 +65,23 @@ 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());
@$document->loadXML($node->C14N());
$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 ? $text : strtolower($text);
}
}

View File

@@ -18,8 +18,9 @@ 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)
@@ -31,27 +32,34 @@ class DateTimeComparator extends ObjectComparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
* @param array $processed List of already processed elements (used to prevent infinite recursion)
*
* @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, array &$processed = [])
{
$delta = new \DateInterval(sprintf('PT%sS', abs($delta)));
/** @var \DateTimeInterface $expected */
/** @var \DateTimeInterface $actual */
$delta = new \DateInterval(sprintf('PT%dS', abs($delta)));
$actualClone = clone $actual;
$actualClone->setTimezone(new \DateTimeZone('UTC'));
$expectedLower = clone $expected;
$expectedUpper = clone $expected;
$expectedLower->setTimezone(new \DateTimeZone('UTC'));
$expectedLower->sub($delta);
if ($actual < $expectedLower->sub($delta) ||
$actual > $expectedUpper->add($delta)) {
$expectedUpper = clone $expected;
$expectedUpper->setTimezone(new \DateTimeZone('UTC'));
$expectedUpper->add($delta);
if ($actual < $expectedLower || $actual > $expectedUpper) {
throw new ComparisonFailure(
$expected,
$actual,
@@ -67,14 +75,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

@@ -25,29 +25,26 @@ class DoubleComparator extends NumericComparator
/**
* 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);
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{

View File

@@ -18,8 +18,9 @@ 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)
@@ -31,7 +32,8 @@ class ExceptionComparator extends ObjectComparator
* 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

@@ -18,32 +18,18 @@ class Factory
/**
* @var Comparator[]
*/
private $comparators = array();
private $customComparators = [];
/**
* @var Comparator[]
*/
private $defaultComparators = [];
/**
* @var Factory
*/
private static $instance;
/**
* Constructs a new factory.
*/
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);
}
/**
* @return Factory
*/
@@ -56,16 +42,31 @@ class Factory
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;
}
@@ -75,16 +76,16 @@ class Factory
/**
* 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)
{
array_unshift($this->comparators, $comparator);
array_unshift($this->customComparators, $comparator);
$comparator->setFactory($this);
}
@@ -92,16 +93,47 @@ 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)
{
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()
{
$this->customComparators = [];
}
private function registerDefaultComparators()
{
$this->registerDefaultComparator(new TypeComparator);
$this->registerDefaultComparator(new ScalarComparator);
$this->registerDefaultComparator(new NumericComparator);
$this->registerDefaultComparator(new DoubleComparator);
$this->registerDefaultComparator(new ArrayComparator);
$this->registerDefaultComparator(new ResourceComparator);
$this->registerDefaultComparator(new ObjectComparator);
$this->registerDefaultComparator(new ExceptionComparator);
$this->registerDefaultComparator(new SplObjectStorageComparator);
$this->registerDefaultComparator(new DOMNodeComparator);
$this->registerDefaultComparator(new MockObjectComparator);
$this->registerDefaultComparator(new DateTimeComparator);
}
private function registerDefaultComparator(Comparator $comparator)
{
array_unshift($this->defaultComparators, $comparator);
$comparator->setFactory($this);
}
}

View File

@@ -18,20 +18,23 @@ 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 \PHPUnit_Framework_MockObject_MockObject || $expected instanceof \PHPUnit\Framework\MockObject\MockObject) &&
($actual instanceof \PHPUnit_Framework_MockObject_MockObject || $actual instanceof \PHPUnit\Framework\MockObject\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

@@ -18,8 +18,9 @@ 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)
@@ -27,24 +28,20 @@ class NumericComparator extends ScalarComparator
// all numerical values, but not if one of them is a double
// or both of them are strings
return is_numeric($expected) && is_numeric($actual) &&
!(is_double($expected) || is_double($actual)) &&
!(is_float($expected) || is_float($actual)) &&
!(is_string($expected) && is_string($actual));
}
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{

View File

@@ -18,8 +18,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)
@@ -30,20 +31,16 @@ class ObjectComparator extends ArrayComparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @param array $processed
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
* @param array $processed List of already processed elements (used to prevent infinite recursion)
*
* @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 = [])
{
if (get_class($actual) !== get_class($expected)) {
throw new ComparisonFailure(
@@ -61,12 +58,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"
@@ -99,7 +96,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

@@ -18,8 +18,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)
@@ -30,17 +31,13 @@ class ResourceComparator extends Comparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{

View File

@@ -18,9 +18,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)
@@ -35,17 +37,13 @@ class ScalarComparator extends Comparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{

View File

@@ -18,8 +18,9 @@ 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)
@@ -30,17 +31,13 @@ class SplObjectStorageComparator extends Comparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{

View File

@@ -18,8 +18,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)
@@ -30,17 +31,13 @@ class TypeComparator extends Comparator
/**
* Asserts that two values are equal.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @param float $delta The allowed numerical distance between two values to
* consider them equal
* @param bool $canonicalize If set to TRUE, arrays are sorted before
* comparison
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
* ignored when comparing string values
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
* @param mixed $expected First value to compare
* @param mixed $actual Second value to compare
* @param float $delta Allowed numerical distance between two values to consider them equal
* @param bool $canonicalize Arrays are sorted before comparison when set to true
* @param bool $ignoreCase Case is ignored when set to true
*
* @throws ComparisonFailure
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{

View File

@@ -10,12 +10,19 @@
namespace SebastianBergmann\Comparator;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ArrayComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class ArrayComparatorTest extends \PHPUnit_Framework_TestCase
class ArrayComparatorTest extends TestCase
{
/**
* @var ArrayComparator
*/
private $comparator;
protected function setUp()
@@ -26,87 +33,87 @@ class ArrayComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsFailsProvider()
{
return array(
array(array(), null),
array(null, array()),
array(null, null)
);
return [
[[], null],
[null, []],
[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),
return [
[
['a' => 1, 'b' => 2],
['b' => 2, 'a' => 1]
],
[
[1],
['1']
],
[
[3, 2, 1],
[2, 3, 1],
0,
true
),
array(
array(2.3),
array(2.5),
],
[
[2.3],
[2.5],
0.5
),
array(
array(array(2.3)),
array(array(2.5)),
],
[
[[2.3]],
[[2.5]],
0.5
),
array(
array(new Struct(2.3)),
array(new Struct(2.5)),
],
[
[new Struct(2.3)],
[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),
return [
[
[],
[0 => 1]
],
[
[0 => 1],
[]
],
[
[0 => null],
[]
],
[
[0 => 1, 1 => 2],
[0 => 1, 1 => 3]
],
[
['a', 'b' => [1, 2]],
['a', 'b' => [2, 1]]
],
[
[2.3],
[4.2],
0.5
),
array(
array(array(2.3)),
array(array(4.2)),
],
[
[[2.3]],
[[4.2]],
0.5
),
array(
array(new Struct(2.3)),
array(new Struct(4.2)),
],
[
[new Struct(2.3)],
[new Struct(4.2)],
0.5
)
);
]
];
}
/**
@@ -115,7 +122,7 @@ class ArrayComparatorTest extends \PHPUnit_Framework_TestCase
public function testAcceptsSucceeds()
{
$this->assertTrue(
$this->comparator->accepts(array(), array())
$this->comparator->accepts([], [])
);
}
@@ -140,9 +147,7 @@ class ArrayComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual, $delta, $canonicalize);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -152,12 +157,11 @@ class ArrayComparatorTest extends \PHPUnit_Framework_TestCase
* @covers ::assertEquals
* @dataProvider assertEqualsFailsProvider
*/
public function testAssertEqualsFails($expected, $actual,$delta = 0.0, $canonicalize = false)
public function testAssertEqualsFails($expected, $actual, $delta = 0.0, $canonicalize = false)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two arrays are equal'
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('Failed asserting that two arrays are equal');
$this->comparator->assertEquals($expected, $actual, $delta, $canonicalize);
}
}

View File

@@ -0,0 +1,58 @@
<?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 PHPUnit\Framework\TestCase;
/**
* @covers SebastianBergmann\Comparator\ComparisonFailure
*/
final class ComparisonFailureTest extends TestCase
{
public function testComparisonFailure()
{
$actual = "\nB\n";
$expected = "\nA\n";
$message = 'Test message';
$failure = new ComparisonFailure(
$expected,
$actual,
'|' . $expected,
'|' . $actual,
false,
$message
);
$this->assertSame($actual, $failure->getActual());
$this->assertSame($expected, $failure->getExpected());
$this->assertSame('|' . $actual, $failure->getActualAsString());
$this->assertSame('|' . $expected, $failure->getExpectedAsString());
$diff = '
--- Expected
+++ Actual
@@ @@
|
-A
+B
';
$this->assertSame($diff, $failure->getDiff());
$this->assertSame($message . $diff, $failure->toString());
}
public function testDiffNotPossible()
{
$failure = new ComparisonFailure('a', 'b', false, false, true, 'test');
$this->assertSame('', $failure->getDiff());
$this->assertSame('test', $failure->toString());
}
}

View File

@@ -12,12 +12,15 @@ namespace SebastianBergmann\Comparator;
use DOMNode;
use DOMDocument;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\DOMNodeComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class DOMNodeComparatorTest extends \PHPUnit_Framework_TestCase
class DOMNodeComparatorTest extends TestCase
{
private $comparator;
@@ -29,78 +32,78 @@ class DOMNodeComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsSucceedsProvider()
{
$document = new DOMDocument;
$node = new DOMNode;
$node = new DOMNode;
return array(
array($document, $document),
array($node, $node),
array($document, $node),
array($node, $document)
);
return [
[$document, $document],
[$node, $node],
[$document, $node],
[$node, $document]
];
}
public function acceptsFailsProvider()
{
$document = new DOMDocument;
return array(
array($document, null),
array(null, $document),
array(null, null)
);
return [
[$document, null],
[null, $document],
[null, null]
];
}
public function assertEqualsSucceedsProvider()
{
return array(
array(
return [
[
$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(
return [
[
$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 = new DOMDocument;
$document->preserveWhiteSpace = false;
$document->loadXML($content);
@@ -139,9 +142,7 @@ class DOMNodeComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -153,10 +154,9 @@ class DOMNodeComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two DOM'
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('Failed asserting that two DOM');
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -13,13 +13,19 @@ namespace SebastianBergmann\Comparator;
use DateTime;
use DateTimeImmutable;
use DateTimeZone;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\DateTimeComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class DateTimeComparatorTest extends \PHPUnit_Framework_TestCase
class DateTimeComparatorTest extends TestCase
{
/**
* @var DateTimeComparator
*/
private $comparator;
protected function setUp()
@@ -31,111 +37,111 @@ class DateTimeComparatorTest extends \PHPUnit_Framework_TestCase
{
$datetime = new DateTime;
return array(
array($datetime, null),
array(null, $datetime),
array(null, null)
);
return [
[$datetime, null],
[null, $datetime],
[null, null]
];
}
public function assertEqualsSucceedsProvider()
{
return array(
array(
return [
[
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(
return [
[
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')
),
);
],
];
}
/**
@@ -172,9 +178,7 @@ class DateTimeComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -186,10 +190,9 @@ class DateTimeComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two DateTime objects are equal.'
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('Failed asserting that two DateTime objects are equal.');
$this->comparator->assertEquals($expected, $actual, $delta);
}
@@ -208,9 +211,11 @@ class DateTimeComparatorTest extends \PHPUnit_Framework_TestCase
*/
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'))
$this->assertNull(
$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

@@ -10,11 +10,15 @@
namespace SebastianBergmann\Comparator;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\DoubleComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class DoubleComparatorTest extends \PHPUnit_Framework_TestCase
class DoubleComparatorTest extends TestCase
{
private $comparator;
@@ -25,59 +29,59 @@ class DoubleComparatorTest extends \PHPUnit_Framework_TestCase
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))
);
return [
[0, 5.0],
[5.0, 0],
['5', 4.5],
[1.2e3, 7E-10],
[3, acos(8)],
[acos(8), 3],
[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)
);
return [
[5, 5],
['4.5', 5],
[0x539, 02471],
[5.0, false],
[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))
);
return [
[2.3, 2.3],
['2.3', 2.3],
[5.0, 5],
[5, 5.0],
[5.0, '5'],
[1.2e3, 1200],
[2.3, 2.5, 0.5],
[3, 3.05, 0.05],
[1.2e3, 1201, 1],
[(string) (1 / 3), 1 - 2 / 3],
[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))
);
return [
[2.3, 4.2],
['2.3', 4.2],
[5.0, '4'],
[5.0, 6],
[1.2e3, 1201],
[2.3, 2.5, 0.2],
[3, 3.05, 0.04],
[3, acos(8)],
[acos(8), 3],
[acos(8), acos(8)]
];
}
/**
@@ -112,9 +116,7 @@ class DoubleComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -126,9 +128,9 @@ class DoubleComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', 'matches expected'
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('matches expected');
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -12,12 +12,15 @@ namespace SebastianBergmann\Comparator;
use \Exception;
use \RuntimeException;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ExceptionComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class ExceptionComparatorTest extends \PHPUnit_Framework_TestCase
class ExceptionComparatorTest extends TestCase
{
private $comparator;
@@ -29,20 +32,20 @@ class ExceptionComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsSucceedsProvider()
{
return array(
array(new Exception, new Exception),
array(new RuntimeException, new RuntimeException),
array(new Exception, new RuntimeException)
);
return [
[new Exception, new Exception],
[new RuntimeException, new RuntimeException],
[new Exception, new RuntimeException]
];
}
public function acceptsFailsProvider()
{
return array(
array(new Exception, null),
array(null, new Exception),
array(null, null)
);
return [
[new Exception, null],
[null, new Exception],
[null, null]
];
}
public function assertEqualsSucceedsProvider()
@@ -50,36 +53,36 @@ class ExceptionComparatorTest extends \PHPUnit_Framework_TestCase
$exception1 = new Exception;
$exception2 = new Exception;
$exception3 = new RunTimeException('Error', 100);
$exception4 = new RunTimeException('Error', 100);
$exception3 = new RuntimeException('Error', 100);
$exception4 = new RuntimeException('Error', 100);
return array(
array($exception1, $exception1),
array($exception1, $exception2),
array($exception3, $exception3),
array($exception3, $exception4)
);
return [
[$exception1, $exception1],
[$exception1, $exception2],
[$exception3, $exception3],
[$exception3, $exception4]
];
}
public function assertEqualsFailsProvider()
{
$typeMessage = 'not instance of expected class';
$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);
$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)
);
return [
[$exception1, $exception2, $equalMessage],
[$exception1, $exception3, $equalMessage],
[$exception1, $exception4, $typeMessage],
[$exception2, $exception3, $equalMessage],
[$exception4, $exception5, $equalMessage]
];
}
/**
@@ -114,9 +117,7 @@ class ExceptionComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -128,9 +129,9 @@ class ExceptionComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual, $message)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage($message);
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -10,57 +10,61 @@
namespace SebastianBergmann\Comparator;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\Factory
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class FactoryTest extends \PHPUnit_Framework_TestCase
class FactoryTest extends 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'),
return [
[null, null, 'SebastianBergmann\\Comparator\\ScalarComparator'],
[null, true, 'SebastianBergmann\\Comparator\\ScalarComparator'],
[true, null, 'SebastianBergmann\\Comparator\\ScalarComparator'],
[true, true, 'SebastianBergmann\\Comparator\\ScalarComparator'],
[false, false, 'SebastianBergmann\\Comparator\\ScalarComparator'],
[true, false, 'SebastianBergmann\\Comparator\\ScalarComparator'],
[false, true, 'SebastianBergmann\\Comparator\\ScalarComparator'],
['', '', 'SebastianBergmann\\Comparator\\ScalarComparator'],
['0', '0', 'SebastianBergmann\\Comparator\\ScalarComparator'],
['0', 0, 'SebastianBergmann\\Comparator\\NumericComparator'],
[0, '0', 'SebastianBergmann\\Comparator\\NumericComparator'],
[0, 0, 'SebastianBergmann\\Comparator\\NumericComparator'],
[1.0, 0, 'SebastianBergmann\\Comparator\\DoubleComparator'],
[0, 1.0, 'SebastianBergmann\\Comparator\\DoubleComparator'],
[1.0, 1.0, 'SebastianBergmann\\Comparator\\DoubleComparator'],
[[1], [1], 'SebastianBergmann\\Comparator\\ArrayComparator'],
[$tmpfile, $tmpfile, 'SebastianBergmann\\Comparator\\ResourceComparator'],
[new \stdClass, new \stdClass, 'SebastianBergmann\\Comparator\\ObjectComparator'],
[new \DateTime, new \DateTime, 'SebastianBergmann\\Comparator\\DateTimeComparator'],
[new \SplObjectStorage, new \SplObjectStorage, 'SebastianBergmann\\Comparator\\SplObjectStorageComparator'],
[new \Exception, new \Exception, 'SebastianBergmann\\Comparator\\ExceptionComparator'],
[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'),
);
[$tmpfile, [1], 'SebastianBergmann\\Comparator\\TypeComparator'],
[[1], $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'],
[$tmpfile, '1', 'SebastianBergmann\\Comparator\\TypeComparator'],
['1', $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'],
[$tmpfile, new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'],
[new \stdClass, $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'],
[new \stdClass, [1], 'SebastianBergmann\\Comparator\\TypeComparator'],
[[1], new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'],
[new \stdClass, '1', 'SebastianBergmann\\Comparator\\TypeComparator'],
['1', new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'],
[new ClassWithToString, '1', 'SebastianBergmann\\Comparator\\ScalarComparator'],
['1', new ClassWithToString, 'SebastianBergmann\\Comparator\\ScalarComparator'],
[1.0, new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'],
[new \stdClass, 1.0, 'SebastianBergmann\\Comparator\\TypeComparator'],
[1.0, [1], 'SebastianBergmann\\Comparator\\TypeComparator'],
[[1], 1.0, 'SebastianBergmann\\Comparator\\TypeComparator'],
];
}
/**
@@ -71,7 +75,7 @@ class FactoryTest extends \PHPUnit_Framework_TestCase
public function testGetComparatorFor($a, $b, $expected)
{
$factory = new Factory;
$actual = $factory->getComparatorFor($a, $b);
$actual = $factory->getComparatorFor($a, $b);
$this->assertInstanceOf($expected, $actual);
}
@@ -85,10 +89,10 @@ class FactoryTest extends \PHPUnit_Framework_TestCase
$factory = new Factory;
$factory->register($comparator);
$a = new TestClass;
$b = new TestClass;
$a = new TestClass;
$b = new TestClass;
$expected = 'SebastianBergmann\\Comparator\\TestClassComparator';
$actual = $factory->getComparatorFor($a, $b);
$actual = $factory->getComparatorFor($a, $b);
$factory->unregister($comparator);
$this->assertInstanceOf($expected, $actual);
@@ -105,11 +109,17 @@ class FactoryTest extends \PHPUnit_Framework_TestCase
$factory->register($comparator);
$factory->unregister($comparator);
$a = new TestClass;
$b = new TestClass;
$a = new TestClass;
$b = new TestClass;
$expected = 'SebastianBergmann\\Comparator\\ObjectComparator';
$actual = $factory->getComparatorFor($a, $b);
$actual = $factory->getComparatorFor($a, $b);
$this->assertInstanceOf($expected, $actual);
}
public function testIsSingleton()
{
$f = Factory::getInstance();
$this->assertSame($f, Factory::getInstance());
}
}

View File

@@ -10,11 +10,16 @@
namespace SebastianBergmann\Comparator;
use PHPUnit\Framework\TestCase;
use stdClass;
/**
* @coversDefaultClass SebastianBergmann\Comparator\MockObjectComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class MockObjectComparatorTest extends \PHPUnit_Framework_TestCase
class MockObjectComparatorTest extends TestCase
{
private $comparator;
@@ -26,90 +31,90 @@ class MockObjectComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsSucceedsProvider()
{
$testmock = $this->getMock('SebastianBergmann\\Comparator\\TestClass');
$stdmock = $this->getMock('stdClass');
$testmock = $this->createMock(TestClass::class);
$stdmock = $this->createMock(stdClass::class);
return array(
array($testmock, $testmock),
array($stdmock, $stdmock),
array($stdmock, $testmock)
);
return [
[$testmock, $testmock],
[$stdmock, $stdmock],
[$stdmock, $testmock]
];
}
public function acceptsFailsProvider()
{
$stdmock = $this->getMock('stdClass');
$stdmock = $this->createMock(stdClass::class);
return array(
array($stdmock, null),
array(null, $stdmock),
array(null, null)
);
return [
[$stdmock, null],
[null, $stdmock],
[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 = $this->getMockBuilder(Book::class)->setMethods(null)->getMock();
$book1->author = $this->getMockBuilder(Author::class)->setMethods(null)->setConstructorArgs(['Terry Pratchett'])->getMock();
$book1->author->books[] = $book1;
$book2 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book2->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratchett'));
$book2 = $this->getMockBuilder(Book::class)->setMethods(null)->getMock();
$book2->author = $this->getMockBuilder(Author::class)->setMethods(null)->setConstructorArgs(['Terry Pratchett'])->getMock();
$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));
$object1 = $this->getMockBuilder(SampleClass::class)->setMethods(null)->setConstructorArgs([4, 8, 15])->getMock();
$object2 = $this->getMockBuilder(SampleClass::class)->setMethods(null)->setConstructorArgs([4, 8, 15])->getMock();
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)),
return [
[$object1, $object1],
[$object1, $object2],
[$book1, $book1],
[$book1, $book2],
[
$this->getMockBuilder(Struct::class)->setMethods(null)->setConstructorArgs([2.3])->getMock(),
$this->getMockBuilder(Struct::class)->setMethods(null)->setConstructorArgs([2.5])->getMock(),
0.5
)
);
]
];
}
public function assertEqualsFailsProvider()
{
$typeMessage = 'is not instance of expected class';
$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 = $this->getMockBuilder(Book::class)->setMethods(null)->getMock();
$book1->author = $this->getMockBuilder(Author::class)->setMethods(null)->setConstructorArgs(['Terry Pratchett'])->getMock();
$book1->author->books[] = $book1;
$book2 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book2->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratch'));
$book2 = $this->getMockBuilder(Book::class)->setMethods(null)->getMock();
$book1->author = $this->getMockBuilder(Author::class)->setMethods(null)->setConstructorArgs(['Terry Pratch'])->getMock();
$book2->author->books[] = $book2;
$book3 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
$book3 = $this->getMockBuilder(Book::class)->setMethods(null)->getMock();
$book3->author = 'Terry Pratchett';
$book4 = $this->getMock('stdClass');
$book4 = $this->createMock(stdClass::class);
$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));
$object1 = $this->getMockBuilder(SampleClass::class)->setMethods(null)->setConstructorArgs([4, 8, 15])->getMock();
$object2 = $this->getMockBuilder(SampleClass::class)->setMethods(null)->setConstructorArgs([16, 23, 42])->getMock();
return array(
array(
$this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15)),
$this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(16, 23, 42)),
return [
[
$this->getMockBuilder(SampleClass::class)->setMethods(null)->setConstructorArgs([4, 8, 15])->getMock(),
$this->getMockBuilder(SampleClass::class)->setMethods(null)->setConstructorArgs([16, 23, 42])->getMock(),
$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)),
],
[$object1, $object2, $equalMessage],
[$book1, $book2, $equalMessage],
[$book3, $book4, $typeMessage],
[
$this->getMockBuilder(Struct::class)->setMethods(null)->setConstructorArgs([2.3])->getMock(),
$this->getMockBuilder(Struct::class)->setMethods(null)->setConstructorArgs([4.2])->getMock(),
$equalMessage,
0.5
)
);
]
];
}
/**
@@ -144,9 +149,7 @@ class MockObjectComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -158,9 +161,9 @@ class MockObjectComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual, $message, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage($message);
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -10,11 +10,15 @@
namespace SebastianBergmann\Comparator;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\NumericComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class NumericComparatorTest extends \PHPUnit_Framework_TestCase
class NumericComparatorTest extends TestCase
{
private $comparator;
@@ -25,47 +29,47 @@ class NumericComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsSucceedsProvider()
{
return array(
array(5, 10),
array(8, '0'),
array('10', 0),
array(0x74c3b00c, 42),
array(0755, 0777)
);
return [
[5, 10],
[8, '0'],
['10', 0],
[0x74c3b00c, 42],
[0755, 0777]
];
}
public function acceptsFailsProvider()
{
return array(
array('5', '10'),
array(8, 5.0),
array(5.0, 8),
array(10, null),
array(false, 12)
);
return [
['5', '10'],
[8, 5.0],
[5.0, 8],
[10, null],
[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),
);
return [
[1337, 1337],
['1337', 1337],
[0x539, 1337],
[02471, 1337],
[1337, 1338, 1],
['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),
);
return [
[1337, 1338],
['1338', 1337],
[0x539, 1338],
[1337, 1339, 1],
['1337', 1340, 2],
];
}
/**
@@ -100,9 +104,7 @@ class NumericComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -114,9 +116,9 @@ class NumericComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', 'matches expected'
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('matches expected');
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -11,12 +11,15 @@
namespace SebastianBergmann\Comparator;
use stdClass;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ObjectComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class ObjectComparatorTest extends \PHPUnit_Framework_TestCase
class ObjectComparatorTest extends TestCase
{
private $comparator;
@@ -28,72 +31,72 @@ class ObjectComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsSucceedsProvider()
{
return array(
array(new TestClass, new TestClass),
array(new stdClass, new stdClass),
array(new stdClass, new TestClass)
);
return [
[new TestClass, new TestClass],
[new stdClass, new stdClass],
[new stdClass, new TestClass]
];
}
public function acceptsFailsProvider()
{
return array(
array(new stdClass, null),
array(null, new stdClass),
array(null, null)
);
return [
[new stdClass, null],
[null, new stdClass],
[null, null]
];
}
public function assertEqualsSucceedsProvider()
{
// cyclic dependencies
$book1 = new Book;
$book1->author = new Author('Terry Pratchett');
$book1 = new Book;
$book1->author = new Author('Terry Pratchett');
$book1->author->books[] = $book1;
$book2 = new Book;
$book2->author = new Author('Terry Pratchett');
$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)
);
return [
[$object1, $object1],
[$object1, $object2],
[$book1, $book1],
[$book1, $book2],
[new Struct(2.3), new Struct(2.5), 0.5]
];
}
public function assertEqualsFailsProvider()
{
$typeMessage = 'is not instance of expected class';
$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 = new Book;
$book1->author = new Author('Terry Pratchett');
$book1->author->books[] = $book1;
$book2 = new Book;
$book2->author = new Author('Terry Pratch');
$book2 = new Book;
$book2->author = new Author('Terry Pratch');
$book2->author->books[] = $book2;
$book3 = new Book;
$book3 = new Book;
$book3->author = 'Terry Pratchett';
$book4 = new stdClass;
$book4 = new stdClass;
$book4->author = 'Terry Pratchett';
$object1 = new SampleClass( 4, 8, 15);
$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)
);
return [
[new SampleClass(4, 8, 15), new SampleClass(16, 23, 42), $equalMessage],
[$object1, $object2, $equalMessage],
[$book1, $book2, $equalMessage],
[$book3, $book4, $typeMessage],
[new Struct(2.3), new Struct(4.2), $equalMessage, 0.5]
];
}
/**
@@ -128,9 +131,7 @@ class ObjectComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual, $delta);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -142,9 +143,9 @@ class ObjectComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual, $message, $delta = 0.0)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage($message);
$this->comparator->assertEquals($expected, $actual, $delta);
}
}

View File

@@ -10,11 +10,15 @@
namespace SebastianBergmann\Comparator;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ResourceComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
class ResourceComparatorTest extends TestCase
{
private $comparator;
@@ -28,22 +32,22 @@ class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
$tmpfile1 = tmpfile();
$tmpfile2 = tmpfile();
return array(
array($tmpfile1, $tmpfile1),
array($tmpfile2, $tmpfile2),
array($tmpfile1, $tmpfile2)
);
return [
[$tmpfile1, $tmpfile1],
[$tmpfile2, $tmpfile2],
[$tmpfile1, $tmpfile2]
];
}
public function acceptsFailsProvider()
{
$tmpfile1 = tmpfile();
return array(
array($tmpfile1, null),
array(null, $tmpfile1),
array(null, null)
);
return [
[$tmpfile1, null],
[null, $tmpfile1],
[null, null]
];
}
public function assertEqualsSucceedsProvider()
@@ -51,10 +55,10 @@ class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
$tmpfile1 = tmpfile();
$tmpfile2 = tmpfile();
return array(
array($tmpfile1, $tmpfile1),
array($tmpfile2, $tmpfile2)
);
return [
[$tmpfile1, $tmpfile1],
[$tmpfile2, $tmpfile2]
];
}
public function assertEqualsFailsProvider()
@@ -62,10 +66,10 @@ class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
$tmpfile1 = tmpfile();
$tmpfile2 = tmpfile();
return array(
array($tmpfile1, $tmpfile2),
array($tmpfile2, $tmpfile1)
);
return [
[$tmpfile1, $tmpfile2],
[$tmpfile2, $tmpfile1]
];
}
/**
@@ -100,9 +104,7 @@ class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -114,7 +116,8 @@ class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException('SebastianBergmann\\Comparator\\ComparisonFailure');
$this->expectException(ComparisonFailure::class);
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -10,11 +10,15 @@
namespace SebastianBergmann\Comparator;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\ScalarComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class ScalarComparatorTest extends \PHPUnit_Framework_TestCase
class ScalarComparatorTest extends TestCase
{
private $comparator;
@@ -25,83 +29,83 @@ class ScalarComparatorTest extends \PHPUnit_Framework_TestCase
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")
);
return [
['string', 'string'],
[new ClassWithToString, 'string'],
['string', new ClassWithToString],
['string', null],
[false, 'string'],
[false, true],
[null, false],
[null, null],
['10', 10],
['', false],
['1', true],
[1, true],
[0, false],
[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())
);
return [
[[], []],
['string', []],
[new ClassWithToString, new ClassWithToString],
[false, new ClassWithToString],
[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)
);
return [
['string', 'string'],
[new ClassWithToString, new ClassWithToString],
['string representation', new ClassWithToString],
[new ClassWithToString, 'string representation'],
['string', 'STRING', true],
['STRING', 'string', true],
['String Representation', new ClassWithToString, true],
[new ClassWithToString, 'String Representation', true],
['10', 10],
['', false],
['1', true],
[1, true],
[0, false],
[0.1, '0.1'],
[false, null],
[false, false],
[true, true],
[null, null]
];
}
public function assertEqualsFailsProvider()
{
$stringException = 'Failed asserting that two strings are equal.';
$otherException = 'matches expected';
$otherException = 'matches expected';
return array(
array("string", "other string", $stringException),
array("string", "STRING", $stringException),
array("STRING", "string", $stringException),
array("string", "other string", $stringException),
return [
['string', 'other string', $stringException],
['string', 'STRING', $stringException],
['STRING', 'string', $stringException],
['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)
);
['9E6666666','9E7777777', $stringException],
[new ClassWithToString, 'does not match', $otherException],
['does not match', new ClassWithToString, $otherException],
[0, 'Foobar', $otherException],
['Foobar', 0, $otherException],
['10', 25, $otherException],
['1', false, $otherException],
['', true, $otherException],
[false, true, $otherException],
[true, false, $otherException],
[null, true, $otherException],
[0, true, $otherException]
];
}
/**
@@ -136,9 +140,7 @@ class ScalarComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual, 0.0, false, $ignoreCase);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -150,9 +152,9 @@ class ScalarComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual, $message)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure', $message
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage($message);
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -12,12 +12,15 @@ namespace SebastianBergmann\Comparator;
use SplObjectStorage;
use stdClass;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\SplObjectStorageComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
class SplObjectStorageComparatorTest extends TestCase
{
private $comparator;
@@ -28,11 +31,11 @@ class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsFailsProvider()
{
return array(
array(new SplObjectStorage, new stdClass),
array(new stdClass, new SplObjectStorage),
array(new stdClass, new stdClass)
);
return [
[new SplObjectStorage, new stdClass],
[new stdClass, new SplObjectStorage],
[new stdClass, new stdClass]
];
}
public function assertEqualsSucceedsProvider()
@@ -51,12 +54,12 @@ class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
$storage4->attach($object2);
$storage4->attach($object1);
return array(
array($storage1, $storage1),
array($storage1, $storage2),
array($storage3, $storage3),
array($storage3, $storage4)
);
return [
[$storage1, $storage1],
[$storage1, $storage2],
[$storage3, $storage3],
[$storage3, $storage4]
];
}
public function assertEqualsFailsProvider()
@@ -73,11 +76,11 @@ class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
$storage3->attach($object2);
$storage3->attach($object1);
return array(
array($storage1, $storage2),
array($storage1, $storage3),
array($storage2, $storage3),
);
return [
[$storage1, $storage2],
[$storage1, $storage3],
[$storage2, $storage3],
];
}
/**
@@ -114,9 +117,7 @@ class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -128,10 +129,20 @@ class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException(
'SebastianBergmann\\Comparator\\ComparisonFailure',
'Failed asserting that two objects are equal.'
);
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('Failed asserting that two objects are equal.');
$this->comparator->assertEquals($expected, $actual);
}
public function testAssertEqualsFails2()
{
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('Failed asserting that two objects are equal.');
$t = new SplObjectStorage();
$t->attach(new \stdClass());
$this->comparator->assertEquals($t, new \SplObjectStorage());
}
}

View File

@@ -11,12 +11,15 @@
namespace SebastianBergmann\Comparator;
use stdClass;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass SebastianBergmann\Comparator\TypeComparator
*
* @uses SebastianBergmann\Comparator\Comparator
* @uses SebastianBergmann\Comparator\Factory
* @uses SebastianBergmann\Comparator\ComparisonFailure
*/
class TypeComparatorTest extends \PHPUnit_Framework_TestCase
class TypeComparatorTest extends TestCase
{
private $comparator;
@@ -27,40 +30,40 @@ class TypeComparatorTest extends \PHPUnit_Framework_TestCase
public function acceptsSucceedsProvider()
{
return array(
array(true, 1),
array(false, array(1)),
array(null, new stdClass),
array(1.0, 5),
array("", "")
);
return [
[true, 1],
[false, [1]],
[null, new stdClass],
[1.0, 5],
['', '']
];
}
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))
);
return [
[true, true],
[true, false],
[false, false],
[null, null],
[new stdClass, new stdClass],
[0, 0],
[1.0, 2.0],
['hello', 'world'],
['', ''],
[[], [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)
);
return [
[true, null],
[null, false],
[1.0, 0],
[new stdClass, []],
['1', 1]
];
}
/**
@@ -84,9 +87,7 @@ class TypeComparatorTest extends \PHPUnit_Framework_TestCase
try {
$this->comparator->assertEquals($expected, $actual);
}
catch (ComparisonFailure $exception) {
} catch (ComparisonFailure $exception) {
}
$this->assertNull($exception, 'Unexpected ComparisonFailure');
@@ -98,7 +99,9 @@ class TypeComparatorTest extends \PHPUnit_Framework_TestCase
*/
public function testAssertEqualsFails($expected, $actual)
{
$this->setExpectedException('SebastianBergmann\\Comparator\\ComparisonFailure', 'does not match expected type');
$this->expectException(ComparisonFailure::class);
$this->expectExceptionMessage('does not match expected type');
$this->comparator->assertEquals($expected, $actual);
}
}

View File

@@ -12,12 +12,11 @@ namespace SebastianBergmann\Comparator;
/**
* An author.
*
*/
class Author
{
// the order of properties is important for testing the cycle!
public $books = array();
public $books = [];
private $name = '';

View File

@@ -12,7 +12,6 @@ namespace SebastianBergmann\Comparator;
/**
* A book.
*
*/
class Book
{

View File

@@ -12,7 +12,6 @@ namespace SebastianBergmann\Comparator;
/**
* A sample class.
*
*/
class SampleClass
{

View File

@@ -12,7 +12,6 @@ namespace SebastianBergmann\Comparator;
/**
* A struct.
*
*/
class Struct
{

View File

@@ -10,5 +10,6 @@
namespace SebastianBergmann\Comparator;
class TestClass {
class TestClass
{
}

View File

@@ -10,5 +10,6 @@
namespace SebastianBergmann\Comparator;
class TestClassComparator extends ObjectComparator {
class TestClassComparator extends ObjectComparator
{
}

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

@@ -1,10 +1,5 @@
.idea
phpunit.xml
composer.lock
composer.phar
vendor/
cache.properties
build/SebastianBergmann
build/LICENSE
build/README.md
build/*.tgz
/.idea
/composer.lock
/vendor
/.php_cs.cache
/from.txt.orig

View File

@@ -1,66 +1,81 @@
<?php
$finder = Symfony\CS\Finder\DefaultFinder::create()
->files()
->in('src')
->in('tests')
->name('*.php');
<?php declare(strict_types=1);
$header = <<<'EOF'
This file is part of sebastian/diff.
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_tag',
'single_line_after_imports',
'single_quote',
'spaces_before_semicolon',
'spaces_cast',
'ternary_spaces',
'trailing_spaces',
'trim_array_spaces',
'unused_use',
'visibility',
'whitespacy_lines'
)
(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.
EOF;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(
[
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true
],
'blank_line_after_namespace' => true,
'blank_line_before_return' => true,
'braces' => true,
'cast_spaces' => true,
'concat_space' => ['spacing' => 'one'],
'declare_strict_types' => true,
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'function_declaration' => true,
'header_comment' => ['header' => $header, 'separate' => 'none'],
'indentation_type' => true,
'line_ending' => true,
'lowercase_constants' => true,
'lowercase_keywords' => true,
'method_argument_space' => true,
'native_function_invocation' => true,
'no_alias_functions' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_closing_tag' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_consecutive_blank_lines' => true,
'no_leading_namespace_whitespace' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_inside_parenthesis' => true,
'no_trailing_comma_in_list_call' => true,
'no_trailing_whitespace' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'phpdoc_align' => true,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'pow_to_exponentiation' => true,
'self_accessor' => true,
'simplified_null_return' => true,
'single_blank_line_at_eof' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_quote' => true,
'ternary_operator_spaces' => true,
'trim_array_spaces' => true,
'visibility_required' => true,
]
)
->finder($finder);
->setFinder(
PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests')
->name('*.php')
);

View File

@@ -1,16 +1,27 @@
language: php
install:
- travis_retry composer install --no-interaction --prefer-source
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
- 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 --coverage-clover=coverage.xml
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
email: false
irc: "irc.freenode.org#phpunit"

View File

@@ -0,0 +1,22 @@
# ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [2.0.1] - 2017-08-03
### Fixed
* Fixed [#66](https://github.com/sebastianbergmann/diff/pull/66): Restored backwards compatibility for PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3
## [2.0.0] - 2017-07-11 [YANKED]
### Added
* Implemented [#64](https://github.com/sebastianbergmann/diff/pull/64): Show line numbers for chunks of a diff
### Removed
* This component is no longer supported on PHP 5.6
[2.0.1]: https://github.com/sebastianbergmann/diff/compare/c341c98ce083db77f896a0aa64f5ee7652915970...2.0.1
[2.0.0]: https://github.com/sebastianbergmann/diff/compare/1.4...c341c98ce083db77f896a0aa64f5ee7652915970

View File

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

View File

@@ -1,16 +1,16 @@
# Diff
# sebastian/diff
Diff implementation for PHP, factored out of PHPUnit into a stand-alone component.
## Installation
To add this package as a local, per-project dependency to your project, simply add a dependency on `sebastian/diff` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Diff:
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
{
"require": {
"sebastian/diff": "*"
}
}
composer require sebastian/diff
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/diff
### Usage

View File

@@ -1,26 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="diff">
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/vendor"/>
<delete file="${basedir}/composer.lock"/>
</target>
<project name="diff" default="setup">
<target name="setup" depends="clean,composer"/>
<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>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/vendor"/>
<delete file="${basedir}/composer.lock"/>
</target>
<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="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

@@ -15,10 +15,10 @@
}
],
"require": {
"php": ">=5.3.3"
"php": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
"phpunit/phpunit": "^6.2"
},
"autoload": {
"classmap": [
@@ -27,7 +27,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "2.0-dev"
}
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.2/phpunit.xsd"
bootstrap="vendor/autoload.php"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="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,17 +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="vendor/autoload.php"
backupGlobals="false"
verbose="true">
<testsuite name="Diff">
<directory suffix="Test.php">tests</directory>
</testsuite>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -10,9 +10,7 @@
namespace SebastianBergmann\Diff;
/**
*/
class Chunk
final class Chunk
{
/**
* @var int
@@ -28,6 +26,7 @@ class Chunk
* @var int
*/
private $end;
/**
* @var int
*/
@@ -38,65 +37,40 @@ class Chunk
*/
private $lines;
/**
* @param int $start
* @param int $startRange
* @param int $end
* @param int $endRange
* @param array $lines
*/
public function __construct($start = 0, $startRange = 1, $end = 0, $endRange = 1, array $lines = array())
public function __construct(int $start = 0, int $startRange = 1, int $end = 0, int $endRange = 1, array $lines = [])
{
$this->start = (int) $start;
$this->startRange = (int) $startRange;
$this->end = (int) $end;
$this->endRange = (int) $endRange;
$this->start = $start;
$this->startRange = $startRange;
$this->end = $end;
$this->endRange = $endRange;
$this->lines = $lines;
}
/**
* @return int
*/
public function getStart()
public function getStart(): int
{
return $this->start;
}
/**
* @return int
*/
public function getStartRange()
public function getStartRange(): int
{
return $this->startRange;
}
/**
* @return int
*/
public function getEnd()
public function getEnd(): int
{
return $this->end;
}
/**
* @return int
*/
public function getEndRange()
public function getEndRange(): int
{
return $this->endRange;
}
/**
* @return array
*/
public function getLines()
public function getLines(): array
{
return $this->lines;
}
/**
* @param array $lines
*/
public function setLines(array $lines)
{
$this->lines = $lines;

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -10,9 +10,7 @@
namespace SebastianBergmann\Diff;
/**
*/
class Diff
final class Diff
{
/**
* @var string
@@ -34,25 +32,19 @@ class Diff
* @param string $to
* @param Chunk[] $chunks
*/
public function __construct($from, $to, array $chunks = array())
public function __construct(string $from, string $to, array $chunks = [])
{
$this->from = $from;
$this->to = $to;
$this->chunks = $chunks;
}
/**
* @return string
*/
public function getFrom()
public function getFrom(): string
{
return $this->from;
}
/**
* @return string
*/
public function getTo()
public function getTo(): string
{
return $this->to;
}
@@ -60,7 +52,7 @@ class Diff
/**
* @return Chunk[]
*/
public function getChunks()
public function getChunks(): array
{
return $this->chunks;
}

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -10,226 +10,179 @@
namespace SebastianBergmann\Diff;
use SebastianBergmann\Diff\LCS\LongestCommonSubsequence;
use SebastianBergmann\Diff\LCS\TimeEfficientImplementation;
use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation;
use SebastianBergmann\Diff\Output\DiffOutputBuilderInterface;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
/**
* Diff implementation.
*/
class Differ
final class Differ
{
/**
* @var string
* @var DiffOutputBuilderInterface
*/
private $header;
private $outputBuilder;
/**
* @var bool
* @param DiffOutputBuilderInterface $outputBuilder
*
* @throws InvalidArgumentException
*/
private $showNonDiffLines;
/**
* @param string $header
*/
public function __construct($header = "--- Original\n+++ New\n", $showNonDiffLines = true)
public function __construct($outputBuilder = null)
{
$this->header = $header;
$this->showNonDiffLines = $showNonDiffLines;
if ($outputBuilder instanceof DiffOutputBuilderInterface) {
$this->outputBuilder = $outputBuilder;
} elseif (null === $outputBuilder) {
$this->outputBuilder = new UnifiedDiffOutputBuilder;
} elseif (\is_string($outputBuilder)) {
// PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3 support
// @see https://github.com/sebastianbergmann/phpunit/issues/2734#issuecomment-314514056
// @deprecated
$this->outputBuilder = new UnifiedDiffOutputBuilder($outputBuilder);
} else {
throw new InvalidArgumentException(
\sprintf(
'Expected builder to be an instance of DiffOutputBuilderInterface, <null> or a string, got %s.',
\is_object($outputBuilder) ? 'instance of "' . \get_class($outputBuilder) . '"' : \gettype($outputBuilder) . ' "' . $outputBuilder . '"'
)
);
}
}
/**
* Returns the diff between two arrays or strings as string.
*
* @param array|string $from
* @param array|string $to
* @param LongestCommonSubsequence $lcs
* @param array|string $from
* @param array|string $to
* @param LongestCommonSubsequenceCalculator|null $lcs
*
* @return string
*/
public function diff($from, $to, LongestCommonSubsequence $lcs = null)
public function diff($from, $to, LongestCommonSubsequenceCalculator $lcs = null): string
{
if (!is_array($from) && !is_string($from)) {
$from = (string) $from;
$from = $this->validateDiffInput($from);
$to = $this->validateDiffInput($to);
$diff = $this->diffToArray($from, $to, $lcs);
return $this->outputBuilder->getDiff($diff);
}
/**
* Casts variable to string if it is not a string or array.
*
* @param mixed $input
*
* @return string
*/
private function validateDiffInput($input): string
{
if (!\is_array($input) && !\is_string($input)) {
return (string) $input;
}
if (!is_array($to) && !is_string($to)) {
$to = (string) $to;
}
$buffer = $this->header;
$diff = $this->diffToArray($from, $to, $lcs);
$inOld = false;
$i = 0;
$old = array();
foreach ($diff as $line) {
if ($line[1] === 0 /* OLD */) {
if ($inOld === false) {
$inOld = $i;
}
} elseif ($inOld !== false) {
if (($i - $inOld) > 5) {
$old[$inOld] = $i - 1;
}
$inOld = false;
}
++$i;
}
$start = isset($old[0]) ? $old[0] : 0;
$end = count($diff);
if ($tmp = array_search($end, $old)) {
$end = $tmp;
}
$newChunk = true;
for ($i = $start; $i < $end; $i++) {
if (isset($old[$i])) {
$buffer .= "\n";
$newChunk = true;
$i = $old[$i];
}
if ($newChunk) {
if ($this->showNonDiffLines === true) {
$buffer .= "@@ @@\n";
}
$newChunk = false;
}
if ($diff[$i][1] === 1 /* ADDED */) {
$buffer .= '+' . $diff[$i][0] . "\n";
} elseif ($diff[$i][1] === 2 /* REMOVED */) {
$buffer .= '-' . $diff[$i][0] . "\n";
} elseif ($this->showNonDiffLines === true) {
$buffer .= ' ' . $diff[$i][0] . "\n";
}
}
return $buffer;
return $input;
}
/**
* Returns the diff between two arrays or strings as array.
*
* Each array element contains two elements:
* - [0] => string $token
* - [0] => mixed $token
* - [1] => 2|1|0
*
* - 2: REMOVED: $token was removed from $from
* - 1: ADDED: $token was added to $from
* - 0: OLD: $token is not changed in $to
*
* @param array|string $from
* @param array|string $to
* @param LongestCommonSubsequence $lcs
* @param array|string $from
* @param array|string $to
* @param LongestCommonSubsequenceCalculator $lcs
*
* @return array
*/
public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
public function diffToArray($from, $to, LongestCommonSubsequenceCalculator $lcs = null): array
{
preg_match_all('(\r\n|\r|\n)', $from, $fromMatches);
preg_match_all('(\r\n|\r|\n)', $to, $toMatches);
if (is_string($from)) {
$from = preg_split('(\r\n|\r|\n)', $from);
if (\is_string($from)) {
$from = $this->splitStringByLines($from);
} elseif (!\is_array($from)) {
throw new \InvalidArgumentException('"from" must be an array or string.');
}
if (is_string($to)) {
$to = preg_split('(\r\n|\r|\n)', $to);
if (\is_string($to)) {
$to = $this->splitStringByLines($to);
} elseif (!\is_array($to)) {
throw new \InvalidArgumentException('"to" must be an array or string.');
}
$start = array();
$end = array();
$fromLength = count($from);
$toLength = count($to);
$length = min($fromLength, $toLength);
for ($i = 0; $i < $length; ++$i) {
if ($from[$i] === $to[$i]) {
$start[] = $from[$i];
unset($from[$i], $to[$i]);
} else {
break;
}
}
$length -= $i;
for ($i = 1; $i < $length; ++$i) {
if ($from[$fromLength - $i] === $to[$toLength - $i]) {
array_unshift($end, $from[$fromLength - $i]);
unset($from[$fromLength - $i], $to[$toLength - $i]);
} else {
break;
}
}
list($from, $to, $start, $end) = self::getArrayDiffParted($from, $to);
if ($lcs === null) {
$lcs = $this->selectLcsImplementation($from, $to);
}
$common = $lcs->calculate(array_values($from), array_values($to));
$diff = array();
if (isset($fromMatches[0]) && $toMatches[0] &&
count($fromMatches[0]) === count($toMatches[0]) &&
$fromMatches[0] !== $toMatches[0]) {
$diff[] = array(
'#Warning: Strings contain different line endings!', 0
);
}
$common = $lcs->calculate(\array_values($from), \array_values($to));
$diff = [];
foreach ($start as $token) {
$diff[] = array($token, 0 /* OLD */);
$diff[] = [$token, 0 /* OLD */];
}
reset($from);
reset($to);
\reset($from);
\reset($to);
foreach ($common as $token) {
while ((($fromToken = reset($from)) !== $token)) {
$diff[] = array(array_shift($from), 2 /* REMOVED */);
while (($fromToken = \reset($from)) !== $token) {
$diff[] = [\array_shift($from), 2 /* REMOVED */];
}
while ((($toToken = reset($to)) !== $token)) {
$diff[] = array(array_shift($to), 1 /* ADDED */);
while (($toToken = \reset($to)) !== $token) {
$diff[] = [\array_shift($to), 1 /* ADDED */];
}
$diff[] = array($token, 0 /* OLD */);
$diff[] = [$token, 0 /* OLD */];
array_shift($from);
array_shift($to);
\array_shift($from);
\array_shift($to);
}
while (($token = array_shift($from)) !== null) {
$diff[] = array($token, 2 /* REMOVED */);
while (($token = \array_shift($from)) !== null) {
$diff[] = [$token, 2 /* REMOVED */];
}
while (($token = array_shift($to)) !== null) {
$diff[] = array($token, 1 /* ADDED */);
while (($token = \array_shift($to)) !== null) {
$diff[] = [$token, 1 /* ADDED */];
}
foreach ($end as $token) {
$diff[] = array($token, 0 /* OLD */);
$diff[] = [$token, 0 /* OLD */];
}
if ($this->detectUnmatchedLineEndings($diff)) {
\array_unshift($diff, ["#Warning: Strings contain different line endings!\n", 3]);
}
return $diff;
}
/**
* Checks if input is string, if so it will split it line-by-line.
*
* @param string $input
*
* @return array
*/
private function splitStringByLines(string $input): array
{
return \preg_split('/(.*\R)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
}
/**
* @param array $from
* @param array $to
*
* @return LongestCommonSubsequence
* @return LongestCommonSubsequenceCalculator
*/
private function selectLcsImplementation(array $from, array $to)
private function selectLcsImplementation(array $from, array $to): LongestCommonSubsequenceCalculator
{
// We do not want to use the time-efficient implementation if its memory
// footprint will probably exceed this value. Note that the footprint
@@ -238,10 +191,10 @@ class Differ
$memoryLimit = 100 * 1024 * 1024;
if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
return new MemoryEfficientImplementation;
return new MemoryEfficientLongestCommonSubsequenceCalculator;
}
return new TimeEfficientImplementation;
return new TimeEfficientLongestCommonSubsequenceCalculator;
}
/**
@@ -250,12 +203,119 @@ class Differ
* @param array $from
* @param array $to
*
* @return int
* @return int|float
*/
private function calculateEstimatedFootprint(array $from, array $to)
{
$itemSize = PHP_INT_SIZE == 4 ? 76 : 144;
$itemSize = PHP_INT_SIZE === 4 ? 76 : 144;
return $itemSize * pow(min(count($from), count($to)), 2);
return $itemSize * \min(\count($from), \count($to)) ** 2;
}
/**
* Returns true if line ends don't match in a diff.
*
* @param array $diff
*
* @return bool
*/
private function detectUnmatchedLineEndings(array $diff): bool
{
$newLineBreaks = ['' => true];
$oldLineBreaks = ['' => true];
foreach ($diff as $entry) {
if (0 === $entry[1]) { /* OLD */
$ln = $this->getLinebreak($entry[0]);
$oldLineBreaks[$ln] = true;
$newLineBreaks[$ln] = true;
} elseif (1 === $entry[1]) { /* ADDED */
$newLineBreaks[$this->getLinebreak($entry[0])] = true;
} elseif (2 === $entry[1]) { /* REMOVED */
$oldLineBreaks[$this->getLinebreak($entry[0])] = true;
}
}
// if either input or output is a single line without breaks than no warning should be raised
if (['' => true] === $newLineBreaks || ['' => true] === $oldLineBreaks) {
return false;
}
// two way compare
foreach ($newLineBreaks as $break => $set) {
if (!isset($oldLineBreaks[$break])) {
return true;
}
}
foreach ($oldLineBreaks as $break => $set) {
if (!isset($newLineBreaks[$break])) {
return true;
}
}
return false;
}
private function getLinebreak($line): string
{
if (!\is_string($line)) {
return '';
}
$lc = \substr($line, -1);
if ("\r" === $lc) {
return "\r";
}
if ("\n" !== $lc) {
return '';
}
if ("\r\n" === \substr($line, -2)) {
return "\r\n";
}
return "\n";
}
private static function getArrayDiffParted(array &$from, array &$to): array
{
$start = [];
$end = [];
\reset($to);
foreach ($from as $k => $v) {
$toK = \key($to);
if ($toK === $k && $v === $to[$k]) {
$start[$k] = $v;
unset($from[$k], $to[$k]);
} else {
break;
}
}
\end($from);
\end($to);
do {
$fromK = \key($from);
$toK = \key($to);
if (null === $fromK || null === $toK || \current($from) !== \current($to)) {
break;
}
\prev($from);
\prev($to);
$end = [$fromK => $from[$fromK]] + $end;
unset($from[$fromK], $to[$toK]);
} while (true);
return [$from, $to, $start, $end];
}
}

View File

@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
interface Exception
{
}

View File

@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
class InvalidArgumentException extends \InvalidArgumentException implements Exception
{
}

View File

@@ -1,93 +0,0 @@
<?php
/*
* This file is part of the Diff 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\Diff\LCS;
/**
* Memory-efficient implementation of longest common subsequence calculation.
*/
class MemoryEfficientImplementation implements LongestCommonSubsequence
{
/**
* Calculates the longest common subsequence of two arrays.
*
* @param array $from
* @param array $to
*
* @return array
*/
public function calculate(array $from, array $to)
{
$cFrom = count($from);
$cTo = count($to);
if ($cFrom == 0) {
return array();
} elseif ($cFrom == 1) {
if (in_array($from[0], $to)) {
return array($from[0]);
} else {
return array();
}
} else {
$i = intval($cFrom / 2);
$fromStart = array_slice($from, 0, $i);
$fromEnd = array_slice($from, $i);
$llB = $this->length($fromStart, $to);
$llE = $this->length(array_reverse($fromEnd), array_reverse($to));
$jMax = 0;
$max = 0;
for ($j = 0; $j <= $cTo; $j++) {
$m = $llB[$j] + $llE[$cTo - $j];
if ($m >= $max) {
$max = $m;
$jMax = $j;
}
}
$toStart = array_slice($to, 0, $jMax);
$toEnd = array_slice($to, $jMax);
return array_merge(
$this->calculate($fromStart, $toStart),
$this->calculate($fromEnd, $toEnd)
);
}
}
/**
* @param array $from
* @param array $to
*
* @return array
*/
private function length(array $from, array $to)
{
$current = array_fill(0, count($to) + 1, 0);
$cFrom = count($from);
$cTo = count($to);
for ($i = 0; $i < $cFrom; $i++) {
$prev = $current;
for ($j = 0; $j < $cTo; $j++) {
if ($from[$i] == $to[$j]) {
$current[$j + 1] = $prev[$j] + 1;
} else {
$current[$j + 1] = max($current[$j], $prev[$j + 1]);
}
}
}
return $current;
}
}

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -10,9 +10,7 @@
namespace SebastianBergmann\Diff;
/**
*/
class Line
final class Line
{
const ADDED = 1;
const REMOVED = 2;
@@ -28,28 +26,18 @@ class Line
*/
private $content;
/**
* @param int $type
* @param string $content
*/
public function __construct($type = self::UNCHANGED, $content = '')
public function __construct(int $type = self::UNCHANGED, string $content = '')
{
$this->type = $type;
$this->content = $content;
}
/**
* @return string
*/
public function getContent()
public function getContent(): string
{
return $this->content;
}
/**
* @return int
*/
public function getType()
public function getType(): int
{
return $this->type;
}

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -8,12 +8,9 @@
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Diff\LCS;
namespace SebastianBergmann\Diff;
/**
* Interface for implementations of longest common subsequence calculation.
*/
interface LongestCommonSubsequence
interface LongestCommonSubsequenceCalculator
{
/**
* Calculates the longest common subsequence of two arrays.
@@ -23,5 +20,5 @@ interface LongestCommonSubsequence
*
* @return array
*/
public function calculate(array $from, array $to);
public function calculate(array $from, array $to): array;
}

View File

@@ -0,0 +1,81 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
{
/**
* {@inheritdoc}
*/
public function calculate(array $from, array $to): array
{
$cFrom = \count($from);
$cTo = \count($to);
if ($cFrom === 0) {
return [];
}
if ($cFrom === 1) {
if (\in_array($from[0], $to, true)) {
return [$from[0]];
}
return [];
}
$i = (int) ($cFrom / 2);
$fromStart = \array_slice($from, 0, $i);
$fromEnd = \array_slice($from, $i);
$llB = $this->length($fromStart, $to);
$llE = $this->length(\array_reverse($fromEnd), \array_reverse($to));
$jMax = 0;
$max = 0;
for ($j = 0; $j <= $cTo; $j++) {
$m = $llB[$j] + $llE[$cTo - $j];
if ($m >= $max) {
$max = $m;
$jMax = $j;
}
}
$toStart = \array_slice($to, 0, $jMax);
$toEnd = \array_slice($to, $jMax);
return \array_merge(
$this->calculate($fromStart, $toStart),
$this->calculate($fromEnd, $toEnd)
);
}
private function length(array $from, array $to): array
{
$current = \array_fill(0, \count($to) + 1, 0);
$cFrom = \count($from);
$cTo = \count($to);
for ($i = 0; $i < $cFrom; $i++) {
$prev = $current;
for ($j = 0; $j < $cTo; $j++) {
if ($from[$i] === $to[$j]) {
$current[$j + 1] = $prev[$j] + 1;
} else {
$current[$j + 1] = \max($current[$j], $prev[$j + 1]);
}
}
}
return $current;
}
}

View File

@@ -0,0 +1,56 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff\Output;
abstract class AbstractChunkOutputBuilder implements DiffOutputBuilderInterface
{
/**
* Takes input of the diff array and returns the common parts.
* Iterates through diff line by line.
*
* @param array $diff
* @param int $lineThreshold
*
* @return array
*/
protected function getCommonChunks(array $diff, int $lineThreshold = 5): array
{
$diffSize = \count($diff);
$capturing = false;
$chunkStart = 0;
$chunkSize = 0;
$commonChunks = [];
for ($i = 0; $i < $diffSize; ++$i) {
if ($diff[$i][1] === 0 /* OLD */) {
if ($capturing === false) {
$capturing = true;
$chunkStart = $i;
$chunkSize = 0;
} else {
++$chunkSize;
}
} elseif ($capturing !== false) {
if ($chunkSize >= $lineThreshold) {
$commonChunks[$chunkStart] = $chunkStart + $chunkSize;
}
$capturing = false;
}
}
if ($capturing !== false && $chunkSize >= $lineThreshold) {
$commonChunks[$chunkStart] = $chunkStart + $chunkSize;
}
return $commonChunks;
}
}

View File

@@ -0,0 +1,63 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff\Output;
/**
* Builds a diff string representation in a loose unified diff format
* listing only changes lines. Does not include line numbers.
*/
final class DiffOnlyOutputBuilder implements DiffOutputBuilderInterface
{
/**
* @var string
*/
private $header;
public function __construct(string $header = "--- Original\n+++ New\n")
{
$this->header = $header;
}
public function getDiff(array $diff): string
{
$buffer = \fopen('php://memory', 'r+b');
if ('' !== $this->header) {
\fwrite($buffer, $this->header);
if ("\n" !== \substr($this->header, -1, 1)) {
\fwrite($buffer, "\n");
}
}
foreach ($diff as $diffEntry) {
if ($diffEntry[1] === 1 /* ADDED */) {
\fwrite($buffer, '+' . $diffEntry[0]);
} elseif ($diffEntry[1] === 2 /* REMOVED */) {
\fwrite($buffer, '-' . $diffEntry[0]);
} elseif ($diffEntry[1] === 3 /* WARNING */) {
\fwrite($buffer, ' ' . $diffEntry[0]);
continue; // Warnings should not be tested for line break, it will always be there
} else { /* Not changed (old) 0 */
continue; // we didn't write the non changs line, so do not add a line break either
}
$lc = \substr($diffEntry[0], -1);
if ($lc !== "\n" && $lc !== "\r") {
\fwrite($buffer, "\n"); // \No newline at end of file
}
}
$diff = \stream_get_contents($buffer, -1, 0);
\fclose($buffer);
return $diff;
}
}

View File

@@ -0,0 +1,19 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff\Output;
/**
* Defines how an output builder should take a generated
* diff array and return a string representation of that diff.
*/
interface DiffOutputBuilderInterface
{
public function getDiff(array $diff): string;
}

View File

@@ -0,0 +1,165 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff\Output;
/**
* Builds a diff string representation in unified diff format in chunks.
*/
final class UnifiedDiffOutputBuilder extends AbstractChunkOutputBuilder
{
/**
* @var string
*/
private $header;
/**
* @var bool
*/
private $addLineNumbers;
public function __construct(string $header = "--- Original\n+++ New\n", bool $addLineNumbers = false)
{
$this->header = $header;
$this->addLineNumbers = $addLineNumbers;
}
public function getDiff(array $diff): string
{
$buffer = \fopen('php://memory', 'r+b');
if ('' !== $this->header) {
\fwrite($buffer, $this->header);
if ("\n" !== \substr($this->header, -1, 1)) {
\fwrite($buffer, "\n");
}
}
$this->writeDiffChunked($buffer, $diff, $this->getCommonChunks($diff));
$diff = \stream_get_contents($buffer, -1, 0);
\fclose($buffer);
return $diff;
}
// `old` is an array with key => value pairs . Each pair represents a start and end index of `diff`
// of a list of elements all containing `same` (0) entries.
private function writeDiffChunked($output, array $diff, array $old)
{
$upperLimit = \count($diff);
$start = 0;
$fromStart = 0;
$toStart = 0;
if (\count($old)) { // no common parts, list all diff entries
\reset($old);
// iterate the diff, go from chunk to chunk skipping common chunk of lines between those
do {
$commonStart = \key($old);
$commonEnd = \current($old);
if ($commonStart !== $start) {
list($fromRange, $toRange) = $this->getChunkRange($diff, $start, $commonStart);
$this->writeChunk($output, $diff, $start, $commonStart, $fromStart, $fromRange, $toStart, $toRange);
$fromStart += $fromRange;
$toStart += $toRange;
}
$start = $commonEnd + 1;
$commonLength = $commonEnd - $commonStart + 1; // calculate number of non-change lines in the common part
$fromStart += $commonLength;
$toStart += $commonLength;
} while (false !== \next($old));
\end($old); // short cut for finding possible last `change entry`
$tmp = \key($old);
\reset($old);
if ($old[$tmp] === $upperLimit - 1) {
$upperLimit = $tmp;
}
}
if ($start < $upperLimit - 1) { // check for trailing (non) diff entries
do {
--$upperLimit;
} while (isset($diff[$upperLimit][1]) && $diff[$upperLimit][1] === 0);
++$upperLimit;
list($fromRange, $toRange) = $this->getChunkRange($diff, $start, $upperLimit);
$this->writeChunk($output, $diff, $start, $upperLimit, $fromStart, $fromRange, $toStart, $toRange);
}
}
private function writeChunk(
$output,
array $diff,
int $diffStartIndex,
int $diffEndIndex,
int $fromStart,
int $fromRange,
int $toStart,
int $toRange
) {
if ($this->addLineNumbers) {
\fwrite($output, '@@ -' . (1 + $fromStart));
if ($fromRange > 1) {
\fwrite($output, ',' . $fromRange);
}
\fwrite($output, ' +' . (1 + $toStart));
if ($toRange > 1) {
\fwrite($output, ',' . $toRange);
}
\fwrite($output, " @@\n");
} else {
\fwrite($output, "@@ @@\n");
}
for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) {
if ($diff[$i][1] === 1 /* ADDED */) {
\fwrite($output, '+' . $diff[$i][0]);
} elseif ($diff[$i][1] === 2 /* REMOVED */) {
\fwrite($output, '-' . $diff[$i][0]);
} else { /* Not changed (old) 0 or Warning 3 */
\fwrite($output, ' ' . $diff[$i][0]);
}
$lc = \substr($diff[$i][0], -1);
if ($lc !== "\n" && $lc !== "\r") {
\fwrite($output, "\n"); // \No newline at end of file
}
}
}
private function getChunkRange(array $diff, int $diffStartIndex, int $diffEndIndex): array
{
$toRange = 0;
$fromRange = 0;
for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) {
if ($diff[$i][1] === 1) { // added
++$toRange;
} elseif ($diff[$i][1] === 2) { // removed
++$fromRange;
} elseif ($diff[$i][1] === 0) { // same
++$fromRange;
++$toRange;
}
}
return [$fromRange, $toRange];
}
}

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -13,82 +13,89 @@ namespace SebastianBergmann\Diff;
/**
* Unified diff parser.
*/
class Parser
final class Parser
{
/**
* @param string $string
*
* @return Diff[]
*/
public function parse($string)
public function parse(string $string): array
{
$lines = preg_split('(\r\n|\r|\n)', $string);
$lineCount = count($lines);
$diffs = array();
$lines = \preg_split('(\r\n|\r|\n)', $string);
if (!empty($lines) && $lines[\count($lines) - 1] === '') {
\array_pop($lines);
}
$lineCount = \count($lines);
$diffs = [];
$diff = null;
$collected = array();
$collected = [];
for ($i = 0; $i < $lineCount; ++$i) {
if (preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
if (\preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
\preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
if ($diff !== null) {
$this->parseFileDiff($diff, $collected);
$diffs[] = $diff;
$collected = array();
$collected = [];
}
$diff = new Diff($fromMatch['file'], $toMatch['file']);
++$i;
} else {
if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
if (\preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
continue;
}
$collected[] = $lines[$i];
}
}
if (count($collected) && ($diff !== null)) {
if ($diff !== null && \count($collected)) {
$this->parseFileDiff($diff, $collected);
$diffs[] = $diff;
}
return $diffs;
}
/**
* @param Diff $diff
* @param array $lines
*/
private function parseFileDiff(Diff $diff, array $lines)
{
$chunks = array();
$chunks = [];
$chunk = null;
foreach ($lines as $line) {
if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
if (\preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
$chunk = new Chunk(
$match['start'],
isset($match['startrange']) ? max(1, $match['startrange']) : 1,
$match['end'],
isset($match['endrange']) ? max(1, $match['endrange']) : 1
(int) $match['start'],
isset($match['startrange']) ? \max(1, (int) $match['startrange']) : 1,
(int) $match['end'],
isset($match['endrange']) ? \max(1, (int) $match['endrange']) : 1
);
$chunks[] = $chunk;
$diffLines = array();
$diffLines = [];
continue;
}
if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
if (\preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
$type = Line::UNCHANGED;
if ($match['type'] == '+') {
if ($match['type'] === '+') {
$type = Line::ADDED;
} elseif ($match['type'] == '-') {
} elseif ($match['type'] === '-') {
$type = Line::REMOVED;
}
$diffLines[] = new Line($type, $match['line']);
if (isset($chunk)) {
if (null !== $chunk) {
$chunk->setLines($diffLines);
}
}

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -8,26 +8,18 @@
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Diff\LCS;
namespace SebastianBergmann\Diff;
/**
* Time-efficient implementation of longest common subsequence calculation.
*/
class TimeEfficientImplementation implements LongestCommonSubsequence
final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
{
/**
* Calculates the longest common subsequence of two arrays.
*
* @param array $from
* @param array $to
*
* @return array
* {@inheritdoc}
*/
public function calculate(array $from, array $to)
public function calculate(array $from, array $to): array
{
$common = array();
$fromLength = count($from);
$toLength = count($to);
$common = [];
$fromLength = \count($from);
$toLength = \count($to);
$width = $fromLength + 1;
$matrix = new \SplFixedArray($width * ($toLength + 1));
@@ -42,7 +34,7 @@ class TimeEfficientImplementation implements LongestCommonSubsequence
for ($i = 1; $i <= $fromLength; ++$i) {
for ($j = 1; $j <= $toLength; ++$j) {
$o = ($j * $width) + $i;
$matrix[$o] = max(
$matrix[$o] = \max(
$matrix[$o - 1],
$matrix[$o - $width],
$from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0
@@ -54,12 +46,13 @@ class TimeEfficientImplementation implements LongestCommonSubsequence
$j = $toLength;
while ($i > 0 && $j > 0) {
if ($from[$i-1] === $to[$j-1]) {
$common[] = $from[$i-1];
if ($from[$i - 1] === $to[$j - 1]) {
$common[] = $from[$i - 1];
--$i;
--$j;
} else {
$o = ($j * $width) + $i;
if ($matrix[$o - $width] > $matrix[$o - 1]) {
--$j;
} else {
@@ -68,6 +61,6 @@ class TimeEfficientImplementation implements LongestCommonSubsequence
}
}
return array_reverse($common);
return \array_reverse($common);
}
}

View File

@@ -0,0 +1,68 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
use PHPUnit\Framework\TestCase;
/**
* @covers SebastianBergmann\Diff\Chunk
*/
final class ChunkTest extends TestCase
{
/**
* @var Chunk
*/
private $chunk;
protected function setUp()
{
$this->chunk = new Chunk;
}
public function testCanBeCreatedWithoutArguments()
{
$this->assertInstanceOf(Chunk::class, $this->chunk);
}
public function testStartCanBeRetrieved()
{
$this->assertSame(0, $this->chunk->getStart());
}
public function testStartRangeCanBeRetrieved()
{
$this->assertSame(1, $this->chunk->getStartRange());
}
public function testEndCanBeRetrieved()
{
$this->assertSame(0, $this->chunk->getEnd());
}
public function testEndRangeCanBeRetrieved()
{
$this->assertSame(1, $this->chunk->getEndRange());
}
public function testLinesCanBeRetrieved()
{
$this->assertSame([], $this->chunk->getLines());
}
public function testLinesCanBeSet()
{
$this->assertSame([], $this->chunk->getLines());
$testValue = ['line0', 'line1'];
$this->chunk->setLines($testValue);
$this->assertSame($testValue, $this->chunk->getLines());
}
}

View File

@@ -0,0 +1,55 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
use PHPUnit\Framework\TestCase;
/**
* @covers SebastianBergmann\Diff\Diff
*
* @uses SebastianBergmann\Diff\Chunk
*/
final class DiffTest extends TestCase
{
public function testGettersAfterConstructionWithDefault()
{
$from = 'line1a';
$to = 'line2a';
$diff = new Diff($from, $to);
$this->assertSame($from, $diff->getFrom());
$this->assertSame($to, $diff->getTo());
$this->assertSame([], $diff->getChunks(), 'Expect chunks to be default value "array()".');
}
public function testGettersAfterConstructionWithChunks()
{
$from = 'line1b';
$to = 'line2b';
$chunks = [new Chunk(), new Chunk(2, 3)];
$diff = new Diff($from, $to, $chunks);
$this->assertSame($from, $diff->getFrom());
$this->assertSame($to, $diff->getTo());
$this->assertSame($chunks, $diff->getChunks(), 'Expect chunks to be passed value.');
}
public function testSetChunksAfterConstruction()
{
$diff = new Diff('line1c', 'line2c');
$this->assertSame([], $diff->getChunks(), 'Expect chunks to be default value "array()".');
$chunks = [new Chunk(), new Chunk(2, 3)];
$diff->setChunks($chunks);
$this->assertSame($chunks, $diff->getChunks(), 'Expect chunks to be passed value.');
}
}

View File

@@ -0,0 +1,83 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
use PHPUnit\Framework\TestCase;
/**
* @requires OS Linux
*/
final class DifferTestTest extends TestCase
{
private $fileFrom;
private $filePatch;
protected function setUp()
{
$dir = \realpath(__DIR__ . '/../') . '/';
$this->fileFrom = $dir . 'from.txt';
$this->filePatch = $dir . 'patch.txt';
}
/**
* @dataProvider provideDiffWithLineNumbers
*/
public function testTheTestProvideDiffWithLineNumbers($expected, $from, $to)
{
$this->runThisTest($expected, $from, $to);
}
public function provideDiffWithLineNumbers()
{
require_once __DIR__ . '/DifferTest.php';
$test = new DifferTest();
$tests = $test->provideDiffWithLineNumbers();
$tests = \array_filter(
$tests,
function ($key) {
return !\is_string($key) || false === \strpos($key, 'non_patch_compat');
},
ARRAY_FILTER_USE_KEY
);
return $tests;
}
private function runThisTest(string $expected, string $from, string $to)
{
$expected = \str_replace('--- Original', '--- from.txt', $expected);
$expected = \str_replace('+++ New', '+++ from.txt', $expected);
@\unlink($this->fileFrom);
@\unlink($this->filePatch);
$this->assertNotFalse(\file_put_contents($this->fileFrom, $from));
$this->assertNotFalse(\file_put_contents($this->filePatch, $expected));
$command = \sprintf(
'patch -u --verbose %s < %s', // --posix
\escapeshellarg($this->fileFrom),
\escapeshellarg($this->filePatch)
);
\exec($command, $output, $d);
$this->assertSame(0, $d, \sprintf('%s | %s', $command, \implode("\n", $output)));
$patched = \file_get_contents($this->fileFrom);
$this->assertSame($patched, $to);
@\unlink($this->fileFrom . '.orig');
@\unlink($this->fileFrom);
@\unlink($this->filePatch);
}
}

View File

@@ -1,175 +0,0 @@
<?php
/*
* This file is part of the Diff 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\Diff\LCS;
use PHPUnit_Framework_TestCase;
/**
* Some of these tests are volontary stressfull, in order to give some approximative benchmark hints.
*/
class TimeEfficientImplementationTest extends PHPUnit_Framework_TestCase
{
private $implementation;
private $memory_limit;
private $stress_sizes = array(1, 2, 3, 100, 500, 1000, 2000);
protected function setUp()
{
$this->memory_limit = ini_get('memory_limit');
ini_set('memory_limit', '256M');
$this->implementation = new TimeEfficientImplementation;
}
protected function tearDown()
{
ini_set('memory_limit', $this->memory_limit);
}
public function testBothEmpty()
{
$from = array();
$to = array();
$common = $this->implementation->calculate($from, $to);
$this->assertEquals(array(), $common);
}
public function testIsStrictComparison()
{
$from = array(
false, 0, 0.0, '', null, array(),
true, 1, 1.0, 'foo', array('foo', 'bar'), array('foo' => 'bar')
);
$to = $from;
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($from, $common);
$to = array(
false, false, false, false, false, false,
true, true, true, true, true, true
);
$expected = array(
false,
true,
);
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($expected, $common);
}
public function testEqualSequences()
{
foreach ($this->stress_sizes as $size) {
$range = range(1, $size);
$from = $range;
$to = $range;
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($range, $common);
}
}
public function testDistinctSequences()
{
$from = array('A');
$to = array('B');
$common = $this->implementation->calculate($from, $to);
$this->assertEquals(array(), $common);
$from = array('A', 'B', 'C');
$to = array('D', 'E', 'F');
$common = $this->implementation->calculate($from, $to);
$this->assertEquals(array(), $common);
foreach ($this->stress_sizes as $size) {
$from = range(1, $size);
$to = range($size + 1, $size * 2);
$common = $this->implementation->calculate($from, $to);
$this->assertEquals(array(), $common);
}
}
public function testCommonSubsequence()
{
$from = array('A', 'C', 'E', 'F', 'G');
$to = array('A', 'B', 'D', 'E', 'H');
$expected = array('A', 'E');
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($expected, $common);
$from = array('A', 'C', 'E', 'F', 'G');
$to = array('B', 'C', 'D', 'E', 'F', 'H');
$expected = array('C', 'E', 'F');
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($expected, $common);
foreach ($this->stress_sizes as $size) {
$from = $size < 2 ? array(1) : range(1, $size + 1, 2);
$to = $size < 3 ? array(1) : range(1, $size + 1, 3);
$expected = $size < 6 ? array(1) : range(1, $size + 1, 6);
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($expected, $common);
}
}
public function testSingleElementSubsequenceAtStart()
{
foreach ($this->stress_sizes as $size) {
$from = range(1, $size);
$to = array_slice($from, 0, 1);
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($to, $common);
}
}
public function testSingleElementSubsequenceAtMiddle()
{
foreach ($this->stress_sizes as $size) {
$from = range(1, $size);
$to = array_slice($from, (int) $size / 2, 1);
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($to, $common);
}
}
public function testSingleElementSubsequenceAtEnd()
{
foreach ($this->stress_sizes as $size) {
$from = range(1, $size);
$to = array_slice($from, $size - 1, 1);
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($to, $common);
}
}
public function testReversedSequences()
{
$from = array('A', 'B');
$to = array('B', 'A');
$expected = array('A');
$common = $this->implementation->calculate($from, $to);
$this->assertEquals($expected, $common);
foreach ($this->stress_sizes as $size) {
$from = range(1, $size);
$to = array_reverse($from);
$common = $this->implementation->calculate($from, $to);
$this->assertEquals(array(1), $common);
}
}
}

View File

@@ -0,0 +1,44 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
use PHPUnit\Framework\TestCase;
/**
* @covers SebastianBergmann\Diff\Line
*/
final class LineTest extends TestCase
{
/**
* @var Line
*/
private $line;
protected function setUp()
{
$this->line = new Line;
}
public function testCanBeCreatedWithoutArguments()
{
$this->assertInstanceOf(Line::class, $this->line);
}
public function testTypeCanBeRetrieved()
{
$this->assertSame(Line::UNCHANGED, $this->line->getType());
}
public function testContentCanBeRetrieved()
{
$this->assertSame('', $this->line->getContent());
}
}

View File

@@ -0,0 +1,201 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
use PHPUnit\Framework\TestCase;
/**
* @coversNothing
*/
abstract class LongestCommonSubsequenceTest extends TestCase
{
/**
* @var LongestCommonSubsequenceCalculator
*/
private $implementation;
/**
* @var string
*/
private $memoryLimit;
/**
* @var int[]
*/
private $stress_sizes = [1, 2, 3, 100, 500, 1000, 2000];
protected function setUp()
{
$this->memoryLimit = \ini_get('memory_limit');
\ini_set('memory_limit', '256M');
$this->implementation = $this->createImplementation();
}
/**
* @return LongestCommonSubsequenceCalculator
*/
abstract protected function createImplementation();
protected function tearDown()
{
\ini_set('memory_limit', $this->memoryLimit);
}
public function testBothEmpty()
{
$from = [];
$to = [];
$common = $this->implementation->calculate($from, $to);
$this->assertSame([], $common);
}
public function testIsStrictComparison()
{
$from = [
false, 0, 0.0, '', null, [],
true, 1, 1.0, 'foo', ['foo', 'bar'], ['foo' => 'bar']
];
$to = $from;
$common = $this->implementation->calculate($from, $to);
$this->assertSame($from, $common);
$to = [
false, false, false, false, false, false,
true, true, true, true, true, true
];
$expected = [
false,
true,
];
$common = $this->implementation->calculate($from, $to);
$this->assertSame($expected, $common);
}
public function testEqualSequences()
{
foreach ($this->stress_sizes as $size) {
$range = \range(1, $size);
$from = $range;
$to = $range;
$common = $this->implementation->calculate($from, $to);
$this->assertSame($range, $common);
}
}
public function testDistinctSequences()
{
$from = ['A'];
$to = ['B'];
$common = $this->implementation->calculate($from, $to);
$this->assertSame([], $common);
$from = ['A', 'B', 'C'];
$to = ['D', 'E', 'F'];
$common = $this->implementation->calculate($from, $to);
$this->assertSame([], $common);
foreach ($this->stress_sizes as $size) {
$from = \range(1, $size);
$to = \range($size + 1, $size * 2);
$common = $this->implementation->calculate($from, $to);
$this->assertSame([], $common);
}
}
public function testCommonSubsequence()
{
$from = ['A', 'C', 'E', 'F', 'G'];
$to = ['A', 'B', 'D', 'E', 'H'];
$expected = ['A', 'E'];
$common = $this->implementation->calculate($from, $to);
$this->assertSame($expected, $common);
$from = ['A', 'C', 'E', 'F', 'G'];
$to = ['B', 'C', 'D', 'E', 'F', 'H'];
$expected = ['C', 'E', 'F'];
$common = $this->implementation->calculate($from, $to);
$this->assertSame($expected, $common);
foreach ($this->stress_sizes as $size) {
$from = $size < 2 ? [1] : \range(1, $size + 1, 2);
$to = $size < 3 ? [1] : \range(1, $size + 1, 3);
$expected = $size < 6 ? [1] : \range(1, $size + 1, 6);
$common = $this->implementation->calculate($from, $to);
$this->assertSame($expected, $common);
}
}
public function testSingleElementSubsequenceAtStart()
{
foreach ($this->stress_sizes as $size) {
$from = \range(1, $size);
$to = \array_slice($from, 0, 1);
$common = $this->implementation->calculate($from, $to);
$this->assertSame($to, $common);
}
}
public function testSingleElementSubsequenceAtMiddle()
{
foreach ($this->stress_sizes as $size) {
$from = \range(1, $size);
$to = \array_slice($from, (int) ($size / 2), 1);
$common = $this->implementation->calculate($from, $to);
$this->assertSame($to, $common);
}
}
public function testSingleElementSubsequenceAtEnd()
{
foreach ($this->stress_sizes as $size) {
$from = \range(1, $size);
$to = \array_slice($from, $size - 1, 1);
$common = $this->implementation->calculate($from, $to);
$this->assertSame($to, $common);
}
}
public function testReversedSequences()
{
$from = ['A', 'B'];
$to = ['B', 'A'];
$expected = ['A'];
$common = $this->implementation->calculate($from, $to);
$this->assertSame($expected, $common);
foreach ($this->stress_sizes as $size) {
$from = \range(1, $size);
$to = \array_reverse($from);
$common = $this->implementation->calculate($from, $to);
$this->assertSame([1], $common);
}
}
public function testStrictTypeCalculate()
{
$diff = $this->implementation->calculate(['5'], ['05']);
$this->assertInternalType('array', $diff);
$this->assertCount(0, $diff);
}
}

View File

@@ -0,0 +1,22 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
/**
* @covers SebastianBergmann\Diff\MemoryEfficientLongestCommonSubsequenceCalculator
*/
final class MemoryEfficientImplementationTest extends LongestCommonSubsequenceTest
{
protected function createImplementation()
{
return new MemoryEfficientLongestCommonSubsequenceCalculator;
}
}

View File

@@ -1,6 +1,6 @@
<?php
<?php declare(strict_types=1);
/*
* This file is part of the Diff package.
* This file is part of sebastian/diff.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
@@ -10,9 +10,16 @@
namespace SebastianBergmann\Diff;
use PHPUnit_Framework_TestCase;
use PHPUnit\Framework\TestCase;
class ParserTest extends PHPUnit_Framework_TestCase
/**
* @covers SebastianBergmann\Diff\Parser
*
* @uses SebastianBergmann\Diff\Chunk
* @uses SebastianBergmann\Diff\Diff
* @uses SebastianBergmann\Diff\Line
*/
final class ParserTest extends TestCase
{
/**
* @var Parser
@@ -26,23 +33,28 @@ class ParserTest extends PHPUnit_Framework_TestCase
public function testParse()
{
$content = file_get_contents(__DIR__ . '/fixtures/patch.txt');
$content = \file_get_contents(__DIR__ . '/fixtures/patch.txt');
$diffs = $this->parser->parse($content);
$this->assertInternalType('array', $diffs);
$this->assertContainsOnlyInstancesOf(Diff::class, $diffs);
$this->assertCount(1, $diffs);
$chunks = $diffs[0]->getChunks();
$this->assertInternalType('array', $chunks);
$this->assertContainsOnlyInstancesOf(Chunk::class, $chunks);
$this->assertCount(1, $chunks);
$this->assertEquals(20, $chunks[0]->getStart());
$this->assertSame(20, $chunks[0]->getStart());
$this->assertCount(5, $chunks[0]->getLines());
$this->assertCount(4, $chunks[0]->getLines());
}
public function testParseWithMultipleChunks()
{
$content = file_get_contents(__DIR__ . '/fixtures/patch2.txt');
$content = \file_get_contents(__DIR__ . '/fixtures/patch2.txt');
$diffs = $this->parser->parse($content);
@@ -51,12 +63,89 @@ class ParserTest extends PHPUnit_Framework_TestCase
$chunks = $diffs[0]->getChunks();
$this->assertCount(3, $chunks);
$this->assertEquals(20, $chunks[0]->getStart());
$this->assertEquals(320, $chunks[1]->getStart());
$this->assertEquals(600, $chunks[2]->getStart());
$this->assertSame(20, $chunks[0]->getStart());
$this->assertSame(320, $chunks[1]->getStart());
$this->assertSame(600, $chunks[2]->getStart());
$this->assertCount(5, $chunks[0]->getLines());
$this->assertCount(5, $chunks[1]->getLines());
$this->assertCount(5, $chunks[2]->getLines());
$this->assertCount(4, $chunks[2]->getLines());
}
public function testParseWithRemovedLines()
{
$content = <<<A
diff --git a/Test.txt b/Test.txt
index abcdefg..abcdefh 100644
--- a/Test.txt
+++ b/Test.txt
@@ -49,9 +49,8 @@
A
-B
A;
$diffs = $this->parser->parse($content);
$this->assertInternalType('array', $diffs);
$this->assertContainsOnlyInstancesOf(Diff::class, $diffs);
$this->assertCount(1, $diffs);
$chunks = $diffs[0]->getChunks();
$this->assertInternalType('array', $chunks);
$this->assertContainsOnlyInstancesOf(Chunk::class, $chunks);
$this->assertCount(1, $chunks);
$chunk = $chunks[0];
$this->assertSame(49, $chunk->getStart());
$this->assertSame(49, $chunk->getEnd());
$this->assertSame(9, $chunk->getStartRange());
$this->assertSame(8, $chunk->getEndRange());
$lines = $chunk->getLines();
$this->assertInternalType('array', $lines);
$this->assertContainsOnlyInstancesOf(Line::class, $lines);
$this->assertCount(2, $lines);
/** @var Line $line */
$line = $lines[0];
$this->assertSame('A', $line->getContent());
$this->assertSame(Line::UNCHANGED, $line->getType());
$line = $lines[1];
$this->assertSame('B', $line->getContent());
$this->assertSame(Line::REMOVED, $line->getType());
}
public function testParseDiffForMulitpleFiles()
{
$content = <<<A
diff --git a/Test.txt b/Test.txt
index abcdefg..abcdefh 100644
--- a/Test.txt
+++ b/Test.txt
@@ -1,3 +1,2 @@
A
-B
diff --git a/Test123.txt b/Test123.txt
index abcdefg..abcdefh 100644
--- a/Test2.txt
+++ b/Test2.txt
@@ -1,2 +1,3 @@
A
+B
A;
$diffs = $this->parser->parse($content);
$this->assertCount(2, $diffs);
/** @var Diff $diff */
$diff = $diffs[0];
$this->assertSame('a/Test.txt', $diff->getFrom());
$this->assertSame('b/Test.txt', $diff->getTo());
$this->assertCount(1, $diff->getChunks());
$diff = $diffs[1];
$this->assertSame('a/Test2.txt', $diff->getFrom());
$this->assertSame('b/Test2.txt', $diff->getTo());
$this->assertCount(1, $diff->getChunks());
}
}

View File

@@ -0,0 +1,22 @@
<?php declare(strict_types=1);
/*
* This file is part of sebastian/diff.
*
* (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\Diff;
/**
* @covers SebastianBergmann\Diff\TimeEfficientLongestCommonSubsequenceCalculator
*/
final class TimeEfficientImplementationTest extends LongestCommonSubsequenceTest
{
protected function createImplementation()
{
return new TimeEfficientLongestCommonSubsequenceCalculator;
}
}

View File

@@ -2,3 +2,4 @@
/vendor
/composer.lock
/composer.phar
/.php_cs.cache

View File

@@ -0,0 +1,79 @@
<?php
$header = <<<'EOF'
This file is part of sebastian/environment.
(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.
EOF;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(
[
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true
],
'blank_line_after_namespace' => true,
'blank_line_before_return' => true,
'braces' => true,
'cast_spaces' => true,
'concat_space' => ['spacing' => 'one'],
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'function_declaration' => true,
#'header_comment' => ['header' => $header, 'separate' => 'none'],
'indentation_type' => true,
'line_ending' => true,
'lowercase_constants' => true,
'lowercase_keywords' => true,
'method_argument_space' => true,
'native_function_invocation' => true,
'no_alias_functions' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_closing_tag' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_consecutive_blank_lines' => true,
'no_leading_namespace_whitespace' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_inside_parenthesis' => true,
'no_trailing_comma_in_list_call' => true,
'no_trailing_whitespace' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'phpdoc_align' => true,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'self_accessor' => true,
'simplified_null_return' => true,
'single_blank_line_at_eof' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_quote' => true,
'ternary_operator_spaces' => true,
'trim_array_spaces' => true,
'visibility_required' => true,
]
)
->setFinder(
PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests')
->name('*.php')
);

View File

@@ -1,16 +1,34 @@
language: php
before_script:
sudo: false
before_install:
- composer self-update
- composer install --no-interaction --prefer-source --dev
install:
- travis_retry composer install --no-interaction --prefer-source
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
- 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 --coverage-clover=coverage.xml
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
email: false

View File

@@ -0,0 +1,51 @@
# Changes in sebastianbergmann/environment
All notable changes in `sebastianbergmann/environment` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [3.1.0] - 2017-07-01
### Added
* Implemented [#21](https://github.com/sebastianbergmann/environment/issues/21): Equivalent of `PHP_OS_FAMILY` (for PHP < 7.2)
## [3.0.4] - 2017-06-20
### Fixed
* Fixed [#20](https://github.com/sebastianbergmann/environment/pull/20): PHP 7 mode of HHVM not forced
## [3.0.3] - 2017-05-18
### Fixed
* Fixed [#18](https://github.com/sebastianbergmann/environment/issues/18): `Uncaught TypeError: preg_match() expects parameter 2 to be string, null given`
## [3.0.2] - 2017-04-21
### Fixed
* Fixed [#17](https://github.com/sebastianbergmann/environment/issues/17): `Uncaught TypeError: trim() expects parameter 1 to be string, boolean given`
## [3.0.1] - 2017-04-21
### Fixed
* Fixed inverted logic in `Runtime::discardsComments()`
## [3.0.0] - 2017-04-21
### Added
* Implemented `Runtime::discardsComments()` for querying whether the PHP runtime discards annotations
### Removed
* This component is no longer supported on PHP 5.6
[3.1.0]: https://github.com/sebastianbergmann/phpunit/compare/3.0...3.1.0
[3.0.4]: https://github.com/sebastianbergmann/phpunit/compare/3.0.3...3.0.4
[3.0.3]: https://github.com/sebastianbergmann/phpunit/compare/3.0.2...3.0.3
[3.0.2]: https://github.com/sebastianbergmann/phpunit/compare/3.0.1...3.0.2
[3.0.1]: https://github.com/sebastianbergmann/phpunit/compare/3.0.0...3.0.1
[3.0.0]: https://github.com/sebastianbergmann/phpunit/compare/2.0...3.0.0

View File

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

View File

@@ -1,72 +1,17 @@
# Environment
# sebastian/environment
This component provides functionality that helps writing PHP code that has runtime-specific (PHP / HHVM) execution paths.
[![Latest Stable Version](https://poser.pugx.org/sebastian/environment/v/stable.png)](https://packagist.org/packages/sebastian/environment)
[![Build Status](https://travis-ci.org/sebastianbergmann/environment.png?branch=master)](https://travis-ci.org/sebastianbergmann/environment)
[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/environment.svg?style=flat-square)](https://packagist.org/packages/sebastian/environment)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.0-8892BF.svg?style=flat-square)](https://php.net/)
[![Build Status](https://travis-ci.org/sebastianbergmann/environment.svg?branch=master)](https://travis-ci.org/sebastianbergmann/environment)
## Installation
To add Environment as a local, per-project dependency to your project, simply add a dependency on `sebastian/environment` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Environment 1.0:
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
{
"require": {
"sebastian/environment": "1.0.*"
}
}
composer require sebastian/environment
## Usage
```php
<?php
use SebastianBergmann\Environment\Runtime;
$runtime = new Runtime;
var_dump($runtime->getNameWithVersion());
var_dump($runtime->getName());
var_dump($runtime->getVersion());
var_dump($runtime->getBinary());
var_dump($runtime->isHHVM());
var_dump($runtime->isPHP());
var_dump($runtime->hasXdebug());
var_dump($runtime->canCollectCodeCoverage());
```
### Output on PHP
$ php --version
PHP 5.5.8 (cli) (built: Jan 9 2014 08:33:30)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
$ php example.php
string(9) "PHP 5.5.8"
string(3) "PHP"
string(5) "5.5.8"
string(14) "'/usr/bin/php'"
bool(false)
bool(true)
bool(true)
bool(true)
### Output on HHVM
$ hhvm --version
HipHop VM 2.4.0-dev (rel)
Compiler: heads/master-0-ga98e57cabee7e7f0d14493ab17d5c7ab0157eb98
Repo schema: 8d6e69287c41c1f09bb4d327421720d1922cfc67
$ hhvm example.php
string(14) "HHVM 2.4.0-dev"
string(4) "HHVM"
string(9) "2.4.0-dev"
string(42) "'/usr/local/src/hhvm/hphp/hhvm/hhvm' --php"
bool(true)
bool(false)
bool(false)
bool(true)
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/environment

View File

@@ -1,26 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="environment">
<project name="environment" 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">
<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 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

@@ -10,11 +10,12 @@
"email": "sebastian@phpunit.de"
}
],
"prefer-stable": true,
"require": {
"php": "^5.3.3 || ^7.0"
"php": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8 || ^5.0"
"phpunit/phpunit": "^6.1"
},
"autoload": {
"classmap": [
@@ -23,7 +24,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
"dev-master": "3.1.x-dev"
}
}
}

View File

@@ -1,12 +1,10 @@
<?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"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.2/phpunit.xsd"
bootstrap="vendor/autoload.php"
backupGlobals="false"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
verbose="true">
<testsuite>
<directory suffix="Test.php">tests</directory>

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