Move into nested docroot

This commit is contained in:
Rob Davies 2017-02-13 15:31:17 +00:00
parent 83a0d3a149
commit c8b70abde9
13405 changed files with 0 additions and 0 deletions

View file

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

View file

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

33
web/vendor/sebastian/comparator/LICENSE vendored Normal file
View file

@ -0,0 +1,33 @@
Comparator
Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,41 @@
[![Build Status](https://travis-ci.org/sebastianbergmann/comparator.svg?branch=master)](https://travis-ci.org/sebastianbergmann/comparator)
# Comparator
This component provides the functionality to compare PHP values for equality.
## Installation
To add Comparator as a local, per-project dependency to your project, simply add a dependency on `sebastian/comparator` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Comparator 1.2:
```JSON
{
"require": {
"sebastian/comparator": "~1.2"
}
}
```
## Usage
```php
<?php
use SebastianBergmann\Comparator\Factory;
use SebastianBergmann\Comparator\ComparisonFailure;
$date1 = new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York'));
$date2 = new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago'));
$factory = new Factory;
$comparator = $factory->getComparatorFor($date1, $date2);
try {
$comparator->assertEquals($date1, $date2);
print "Dates match";
}
catch (ComparisonFailure $failure) {
print "Dates don't match";
}
```

View file

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

View file

@ -0,0 +1,11 @@
<?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

@ -0,0 +1,44 @@
{
"name": "sebastian/comparator",
"description": "Provides the functionality to compare PHP values for equality",
"keywords": ["comparator","compare","equality"],
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
}
],
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.2",
"sebastian/exporter": "~1.2"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
}
}

View file

@ -0,0 +1,21 @@
<?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

@ -0,0 +1,136 @@
<?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;
/**
* Compares arrays for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return is_array($expected) && is_array($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
* @param array $processed
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
{
if ($canonicalize) {
sort($expected);
sort($actual);
}
$remaining = $actual;
$expString = $actString = "Array (\n";
$equal = true;
foreach ($expected as $key => $value) {
unset($remaining[$key]);
if (!array_key_exists($key, $actual)) {
$expString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
);
$equal = false;
continue;
}
try {
$comparator = $this->factory->getComparatorFor($value, $actual[$key]);
$comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
$expString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
);
$actString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($actual[$key])
);
} catch (ComparisonFailure $e) {
$expString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$e->getExpectedAsString()
? $this->indent($e->getExpectedAsString())
: $this->exporter->shortenedExport($e->getExpected())
);
$actString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$e->getActualAsString()
? $this->indent($e->getActualAsString())
: $this->exporter->shortenedExport($e->getActual())
);
$equal = false;
}
}
foreach ($remaining as $key => $value) {
$actString .= sprintf(
" %s => %s\n",
$this->exporter->export($key),
$this->exporter->shortenedExport($value)
);
$equal = false;
}
$expString .= ')';
$actString .= ')';
if (!$equal) {
throw new ComparisonFailure(
$expected,
$actual,
$expString,
$actString,
false,
'Failed asserting that two arrays are equal.'
);
}
}
protected function indent($lines)
{
return trim(str_replace("\n", "\n ", $lines));
}
}

View file

@ -0,0 +1,68 @@
<?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 SebastianBergmann\Exporter\Exporter;
/**
* Abstract base class for comparators which compare values for equality.
*/
abstract class Comparator
{
/**
* @var Factory
*/
protected $factory;
/**
* @var Exporter
*/
protected $exporter;
public function __construct()
{
$this->exporter = new Exporter;
}
/**
* @param Factory $factory
*/
public function setFactory(Factory $factory)
{
$this->factory = $factory;
}
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return bool
*/
abstract public function accepts($expected, $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.
*/
abstract public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false);
}

View file

@ -0,0 +1,129 @@
<?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 SebastianBergmann\Diff\Differ;
/**
* Thrown when an assertion for string equality failed.
*/
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;
/**
* @var bool
*/
protected $identical;
/**
* Optional message which is placed in front of the first line
* returned by toString().
* @var string
*/
protected $message;
/**
* Initialises with the expected value and the actual value.
*
* @param mixed $expected Expected value retrieved.
* @param mixed $actual Actual value retrieved.
* @param string $expectedAsString
* @param string $actualAsString
* @param bool $identical
* @param string $message A string which is prefixed on all returned lines
* in the difference output.
*/
public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = false, $message = '')
{
$this->expected = $expected;
$this->actual = $actual;
$this->expectedAsString = $expectedAsString;
$this->actualAsString = $actualAsString;
$this->message = $message;
}
/**
* @return mixed
*/
public function getActual()
{
return $this->actual;
}
/**
* @return mixed
*/
public function getExpected()
{
return $this->expected;
}
/**
* @return string
*/
public function getActualAsString()
{
return $this->actualAsString;
}
/**
* @return string
*/
public function getExpectedAsString()
{
return $this->expectedAsString;
}
/**
* @return string
*/
public function getDiff()
{
if (!$this->actualAsString && !$this->expectedAsString) {
return '';
}
$differ = new Differ("\n--- Expected\n+++ Actual\n");
return $differ->diff($this->expectedAsString, $this->actualAsString);
}
/**
* @return string
*/
public function toString()
{
return $this->message . $this->getDiff();
}
}

View file

@ -0,0 +1,110 @@
<?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 DOMDocument;
use DOMNode;
/**
* Compares DOMNode instances for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return $expected instanceof DOMNode && $actual instanceof DOMNode;
}
/**
* 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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
$expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
$actualAsString = $this->nodeToText($actual, true, $ignoreCase);
if ($expectedAsString !== $actualAsString) {
if ($expected instanceof DOMDocument) {
$type = 'documents';
} else {
$type = 'nodes';
}
throw new ComparisonFailure(
$expected,
$actual,
$expectedAsString,
$actualAsString,
false,
sprintf("Failed asserting that two DOM %s are equal.\n", $type)
);
}
}
/**
* 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)
{
if ($canonicalize) {
$document = new DOMDocument;
$document->loadXML($node->C14N());
$node = $document;
}
if ($node instanceof DOMDocument) {
$document = $node;
} else {
$document = $node->ownerDocument;
}
$document->formatOutput = true;
$document->normalizeDocument();
if ($node instanceof DOMDocument) {
$text = $node->saveXML();
} else {
$text = $document->saveXML($node);
}
if ($ignoreCase) {
$text = strtolower($text);
}
return $text;
}
}

View file

@ -0,0 +1,80 @@
<?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;
/**
* Compares DateTimeInterface instances for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return ($expected instanceof \DateTime || $expected instanceof \DateTimeInterface) &&
($actual instanceof \DateTime || $actual instanceof \DateTimeInterface);
}
/**
* 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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
$delta = new \DateInterval(sprintf('PT%sS', abs($delta)));
$expectedLower = clone $expected;
$expectedUpper = clone $expected;
if ($actual < $expectedLower->sub($delta) ||
$actual > $expectedUpper->add($delta)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->dateTimeToString($expected),
$this->dateTimeToString($actual),
false,
'Failed asserting that two DateTime objects are equal.'
);
}
}
/**
* 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
*/
protected function dateTimeToString($datetime)
{
$string = $datetime->format(\DateTime::ISO8601);
return $string ? $string : 'Invalid DateTimeInterface object';
}
}

View file

@ -0,0 +1,60 @@
<?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;
/**
* Compares doubles for equality.
*/
class DoubleComparator extends NumericComparator
{
/**
* Smallest value available in PHP.
*
* @var float
*/
const EPSILON = 0.0000000001;
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return bool
*/
public function accepts($expected, $actual)
{
return (is_double($expected) || is_double($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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if ($delta == 0) {
$delta = self::EPSILON;
}
parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase);
}
}

View file

@ -0,0 +1,51 @@
<?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;
/**
* Compares Exception instances for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return $expected instanceof \Exception && $actual instanceof \Exception;
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
*/
protected function toArray($object)
{
$array = parent::toArray($object);
unset(
$array['file'],
$array['line'],
$array['trace'],
$array['string'],
$array['xdebug_message']
);
return $array;
}
}

View file

@ -0,0 +1,107 @@
<?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;
/**
* Factory for comparators which compare values for equality.
*/
class Factory
{
/**
* @var Comparator[]
*/
private $comparators = array();
/**
* @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
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self;
}
return self::$instance;
}
/**
* Returns the correct comparator for comparing two values.
*
* @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) {
if ($comparator->accepts($expected, $actual)) {
return $comparator;
}
}
}
/**
* Registers a new comparator.
*
* This comparator will be returned by getInstance() 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
* before those of the other comparators.
*
* @param Comparator $comparator The registered comparator
*/
public function register(Comparator $comparator)
{
array_unshift($this->comparators, $comparator);
$comparator->setFactory($this);
}
/**
* Unregisters a comparator.
*
* This comparator will no longer be returned by getInstance().
*
* @param Comparator $comparator The unregistered comparator
*/
public function unregister(Comparator $comparator)
{
foreach ($this->comparators as $key => $_comparator) {
if ($comparator === $_comparator) {
unset($this->comparators[$key]);
}
}
}
}

View file

@ -0,0 +1,45 @@
<?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;
/**
* Compares PHPUnit_Framework_MockObject_MockObject instances for equality.
*/
class MockObjectComparator extends ObjectComparator
{
/**
* Returns whether the comparator can compare two values.
*
* @param mixed $expected The first value to compare
* @param mixed $actual The second value to compare
* @return bool
*/
public function accepts($expected, $actual)
{
return $expected 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
* @return array
*/
protected function toArray($object)
{
$array = parent::toArray($object);
unset($array['__phpunit_invocationMocker']);
return $array;
}
}

View file

@ -0,0 +1,72 @@
<?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;
/**
* Compares numerical values for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
// all numerical values, but not if one of them is a double
// or both of them are strings
return is_numeric($expected) && is_numeric($actual) &&
!(is_double($expected) || is_double($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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if (is_infinite($actual) && is_infinite($expected)) {
return;
}
if ((is_infinite($actual) xor is_infinite($expected)) ||
(is_nan($actual) or is_nan($expected)) ||
abs($actual - $expected) > $delta) {
throw new ComparisonFailure(
$expected,
$actual,
'',
'',
false,
sprintf(
'Failed asserting that %s matches expected %s.',
$this->exporter->export($actual),
$this->exporter->export($expected)
)
);
}
}
}

View file

@ -0,0 +1,109 @@
<?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;
/**
* Compares objects for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return is_object($expected) && is_object($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
* @param array $processed
* @throws ComparisonFailure Thrown when the comparison
* fails. Contains information about the
* specific errors that lead to the failure.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
{
if (get_class($actual) !== get_class($expected)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
sprintf(
'%s is not instance of expected class "%s".',
$this->exporter->export($actual),
get_class($expected)
)
);
}
// don't compare twice to allow for cyclic dependencies
if (in_array(array($actual, $expected), $processed, true) ||
in_array(array($expected, $actual), $processed, true)) {
return;
}
$processed[] = array($actual, $expected);
// don't compare objects if they are identical
// this helps to avoid the error "maximum function nesting level reached"
// CAUTION: this conditional clause is not tested
if ($actual !== $expected) {
try {
parent::assertEquals(
$this->toArray($expected),
$this->toArray($actual),
$delta,
$canonicalize,
$ignoreCase,
$processed
);
} catch (ComparisonFailure $e) {
throw new ComparisonFailure(
$expected,
$actual,
// replace "Array" with "MyClass object"
substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5),
substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5),
false,
'Failed asserting that two objects are equal.'
);
}
}
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
*/
protected function toArray($object)
{
return $this->exporter->toArray($object);
}
}

View file

@ -0,0 +1,56 @@
<?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;
/**
* Compares resources for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return is_resource($expected) && is_resource($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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if ($actual != $expected) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual)
);
}
}
}

View file

@ -0,0 +1,94 @@
<?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;
/**
* Compares scalar or NULL values for equality.
*/
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
* @return bool
* @since Method available since Release 3.6.0
*/
public function accepts($expected, $actual)
{
return ((is_scalar($expected) xor null === $expected) &&
(is_scalar($actual) xor null === $actual))
// allow comparison between strings and objects featuring __toString()
|| (is_string($expected) && is_object($actual) && method_exists($actual, '__toString'))
|| (is_object($expected) && method_exists($expected, '__toString') && is_string($actual));
}
/**
* 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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
$expectedToCompare = $expected;
$actualToCompare = $actual;
// always compare as strings to avoid strange behaviour
// otherwise 0 == 'Foobar'
if (is_string($expected) || is_string($actual)) {
$expectedToCompare = (string) $expectedToCompare;
$actualToCompare = (string) $actualToCompare;
if ($ignoreCase) {
$expectedToCompare = strtolower($expectedToCompare);
$actualToCompare = strtolower($actualToCompare);
}
}
if ($expectedToCompare != $actualToCompare) {
if (is_string($expected) && is_string($actual)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two strings are equal.'
);
}
throw new ComparisonFailure(
$expected,
$actual,
// no diff is required
'',
'',
false,
sprintf(
'Failed asserting that %s matches expected %s.',
$this->exporter->export($actual),
$this->exporter->export($expected)
)
);
}
}
}

View file

@ -0,0 +1,73 @@
<?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;
/**
* Compares \SplObjectStorage instances for equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return $expected instanceof \SplObjectStorage && $actual instanceof \SplObjectStorage;
}
/**
* 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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
foreach ($actual as $object) {
if (!$expected->contains($object)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two objects are equal.'
);
}
}
foreach ($expected as $object) {
if (!$actual->contains($object)) {
throw new ComparisonFailure(
$expected,
$actual,
$this->exporter->export($expected),
$this->exporter->export($actual),
false,
'Failed asserting that two objects are equal.'
);
}
}
}
}

View file

@ -0,0 +1,63 @@
<?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;
/**
* Compares values for type equality.
*/
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
* @return bool
*/
public function accepts($expected, $actual)
{
return true;
}
/**
* 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.
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if (gettype($expected) != gettype($actual)) {
throw new ComparisonFailure(
$expected,
$actual,
// we don't need a diff
'',
'',
false,
sprintf(
'%s does not match expected type "%s".',
$this->exporter->shortenedExport($actual),
gettype($expected)
)
);
}
}
}

10
web/vendor/sebastian/diff/.gitignore vendored Normal file
View file

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

16
web/vendor/sebastian/diff/.travis.yml vendored Normal file
View file

@ -0,0 +1,16 @@
language: php
install:
- travis_retry composer install --no-interaction --prefer-source
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
notifications:
email: false
irc: "irc.freenode.org#phpunit"

33
web/vendor/sebastian/diff/LICENSE vendored Normal file
View file

@ -0,0 +1,33 @@
Diff
Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

126
web/vendor/sebastian/diff/README.md vendored Normal file
View file

@ -0,0 +1,126 @@
# 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:
{
"require": {
"sebastian/diff": "*"
}
}
### Usage
The `Differ` class can be used to generate a textual representation of the difference between two strings:
```php
use SebastianBergmann\Diff\Differ;
$differ = new Differ;
print $differ->diff('foo', 'bar');
```
The code above yields the output below:
--- Original
+++ New
@@ @@
-foo
+bar
The `Parser` class can be used to parse a unified diff into an object graph:
```php
use SebastianBergmann\Diff\Parser;
use SebastianBergmann\Git;
$git = new Git('/usr/local/src/money');
$diff = $git->getDiff(
'948a1a07768d8edd10dcefa8315c1cbeffb31833',
'c07a373d2399f3e686234c4f7f088d635eb9641b'
);
$parser = new Parser;
print_r($parser->parse($diff));
```
The code above yields the output below:
Array
(
[0] => SebastianBergmann\Diff\Diff Object
(
[from:SebastianBergmann\Diff\Diff:private] => a/tests/MoneyTest.php
[to:SebastianBergmann\Diff\Diff:private] => b/tests/MoneyTest.php
[chunks:SebastianBergmann\Diff\Diff:private] => Array
(
[0] => SebastianBergmann\Diff\Chunk Object
(
[start:SebastianBergmann\Diff\Chunk:private] => 87
[startRange:SebastianBergmann\Diff\Chunk:private] => 7
[end:SebastianBergmann\Diff\Chunk:private] => 87
[endRange:SebastianBergmann\Diff\Chunk:private] => 7
[lines:SebastianBergmann\Diff\Chunk:private] => Array
(
[0] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 3
[content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::add
)
[1] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 3
[content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::newMoney
)
[2] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 3
[content:SebastianBergmann\Diff\Line:private] => */
)
[3] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 2
[content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyWithSameCurrencyObjectCanBeAdded()
)
[4] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 1
[content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyObjectWithSameCurrencyCanBeAdded()
)
[5] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 3
[content:SebastianBergmann\Diff\Line:private] => {
)
[6] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 3
[content:SebastianBergmann\Diff\Line:private] => $a = new Money(1, new Currency('EUR'));
)
[7] => SebastianBergmann\Diff\Line Object
(
[type:SebastianBergmann\Diff\Line:private] => 3
[content:SebastianBergmann\Diff\Line:private] => $b = new Money(2, new Currency('EUR'));
)
)
)
)
)
)

26
web/vendor/sebastian/diff/build.xml vendored Normal file
View file

@ -0,0 +1,26 @@
<?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>
<target name="composer" depends="clean" description="Install dependencies with Composer">
<tstamp>
<format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
</tstamp>
<delete>
<fileset dir="${basedir}">
<include name="composer.phar" />
<date datetime="${thirty.days.ago}" when="before"/>
</fileset>
</delete>
<get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
<exec executable="php">
<arg value="composer.phar"/>
<arg value="install"/>
</exec>
</target>
</project>

33
web/vendor/sebastian/diff/composer.json vendored Normal file
View file

@ -0,0 +1,33 @@
{
"name": "sebastian/diff",
"description": "Diff implementation",
"keywords": ["diff"],
"homepage": "http://www.github.com/sebastianbergmann/diff",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Kore Nordmann",
"email": "mail@kore-nordmann.de"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
}
}

View file

@ -0,0 +1,17 @@
<?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>

110
web/vendor/sebastian/diff/src/Chunk.php vendored Normal file
View file

@ -0,0 +1,110 @@
<?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;
/**
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
class Chunk
{
/**
* @var int
*/
private $start;
/**
* @var int
*/
private $startRange;
/**
* @var int
*/
private $end;
/**
* @var int
*/
private $endRange;
/**
* @var array
*/
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())
{
$this->start = (int) $start;
$this->startRange = (int) $startRange;
$this->end = (int) $end;
$this->endRange = (int) $endRange;
$this->lines = $lines;
}
/**
* @return int
*/
public function getStart()
{
return $this->start;
}
/**
* @return int
*/
public function getStartRange()
{
return $this->startRange;
}
/**
* @return int
*/
public function getEnd()
{
return $this->end;
}
/**
* @return int
*/
public function getEndRange()
{
return $this->endRange;
}
/**
* @return array
*/
public function getLines()
{
return $this->lines;
}
/**
* @param array $lines
*/
public function setLines(array $lines)
{
$this->lines = $lines;
}
}

81
web/vendor/sebastian/diff/src/Diff.php vendored Normal file
View file

@ -0,0 +1,81 @@
<?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;
/**
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
class Diff
{
/**
* @var string
*/
private $from;
/**
* @var string
*/
private $to;
/**
* @var Chunk[]
*/
private $chunks;
/**
* @param string $from
* @param string $to
* @param Chunk[] $chunks
*/
public function __construct($from, $to, array $chunks = array())
{
$this->from = $from;
$this->to = $to;
$this->chunks = $chunks;
}
/**
* @return string
*/
public function getFrom()
{
return $this->from;
}
/**
* @return string
*/
public function getTo()
{
return $this->to;
}
/**
* @return Chunk[]
*/
public function getChunks()
{
return $this->chunks;
}
/**
* @param Chunk[] $chunks
*/
public function setChunks(array $chunks)
{
$this->chunks = $chunks;
}
}

256
web/vendor/sebastian/diff/src/Differ.php vendored Normal file
View file

@ -0,0 +1,256 @@
<?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;
use SebastianBergmann\Diff\LCS\LongestCommonSubsequence;
use SebastianBergmann\Diff\LCS\TimeEfficientImplementation;
use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation;
/**
* Diff implementation.
*
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
class Differ
{
/**
* @var string
*/
private $header;
/**
* @param string $header
*/
public function __construct($header = "--- Original\n+++ New\n")
{
$this->header = $header;
}
/**
* Returns the diff between two arrays or strings as string.
*
* @param array|string $from
* @param array|string $to
* @param LongestCommonSubsequence $lcs
* @return string
*/
public function diff($from, $to, LongestCommonSubsequence $lcs = null)
{
if (!is_array($from) && !is_string($from)) {
$from = (string) $from;
}
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) {
$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";
} else {
$buffer .= ' ' . $diff[$i][0] . "\n";
}
}
return $buffer;
}
/**
* Returns the diff between two arrays or strings as array.
*
* Each array element contains two elements:
* - [0] => string $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
* @return array
*/
public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
{
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($to)) {
$to = preg_split('(\r\n|\r|\n)', $to);
}
$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;
}
}
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
);
}
foreach ($start as $token) {
$diff[] = array($token, 0 /* OLD */);
}
reset($from);
reset($to);
foreach ($common as $token) {
while ((($fromToken = reset($from)) !== $token)) {
$diff[] = array(array_shift($from), 2 /* REMOVED */);
}
while ((($toToken = reset($to)) !== $token)) {
$diff[] = array(array_shift($to), 1 /* ADDED */);
}
$diff[] = array($token, 0 /* OLD */);
array_shift($from);
array_shift($to);
}
while (($token = array_shift($from)) !== null) {
$diff[] = array($token, 2 /* REMOVED */);
}
while (($token = array_shift($to)) !== null) {
$diff[] = array($token, 1 /* ADDED */);
}
foreach ($end as $token) {
$diff[] = array($token, 0 /* OLD */);
}
return $diff;
}
/**
* @param array $from
* @param array $to
* @return LongestCommonSubsequence
*/
private function selectLcsImplementation(array $from, array $to)
{
// We do not want to use the time-efficient implementation if its memory
// footprint will probably exceed this value. Note that the footprint
// calculation is only an estimation for the matrix and the LCS method
// will typically allocate a bit more memory than this.
$memoryLimit = 100 * 1024 * 1024;
if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
return new MemoryEfficientImplementation;
}
return new TimeEfficientImplementation;
}
/**
* Calculates the estimated memory footprint for the DP-based method.
*
* @param array $from
* @param array $to
* @return integer
*/
private function calculateEstimatedFootprint(array $from, array $to)
{
$itemSize = PHP_INT_SIZE == 4 ? 76 : 144;
return $itemSize * pow(min(count($from), count($to)), 2);
}
}

View file

@ -0,0 +1,33 @@
<?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;
/**
* Interface for implementations of longest common subsequence calculation.
*
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
interface LongestCommonSubsequence
{
/**
* Calculates the longest common subsequence of two arrays.
*
* @param array $from
* @param array $to
* @return array
*/
public function calculate(array $from, array $to);
}

View file

@ -0,0 +1,98 @@
<?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.
*
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Denes Lados <lados.denes@gmail.com>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
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

@ -0,0 +1,79 @@
<?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;
/**
* Time-efficient implementation of longest common subsequence calculation.
*
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
class TimeEfficientImplementation 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)
{
$common = array();
$fromLength = count($from);
$toLength = count($to);
$width = $fromLength + 1;
$matrix = new \SplFixedArray($width * ($toLength + 1));
for ($i = 0; $i <= $fromLength; ++$i) {
$matrix[$i] = 0;
}
for ($j = 0; $j <= $toLength; ++$j) {
$matrix[$j * $width] = 0;
}
for ($i = 1; $i <= $fromLength; ++$i) {
for ($j = 1; $j <= $toLength; ++$j) {
$o = ($j * $width) + $i;
$matrix[$o] = max(
$matrix[$o - 1],
$matrix[$o - $width],
$from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0
);
}
}
$i = $fromLength;
$j = $toLength;
while ($i > 0 && $j > 0) {
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 {
--$i;
}
}
}
return array_reverse($common);
}
}

62
web/vendor/sebastian/diff/src/Line.php vendored Normal file
View file

@ -0,0 +1,62 @@
<?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;
/**
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
class Line
{
const ADDED = 1;
const REMOVED = 2;
const UNCHANGED = 3;
/**
* @var int
*/
private $type;
/**
* @var string
*/
private $content;
/**
* @param int $type
* @param string $content
*/
public function __construct($type = self::UNCHANGED, $content = '')
{
$this->type = $type;
$this->content = $content;
}
/**
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* @return int
*/
public function getType()
{
return $this->type;
}
}

105
web/vendor/sebastian/diff/src/Parser.php vendored Normal file
View file

@ -0,0 +1,105 @@
<?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;
/**
* Unified diff parser.
*
* @package Diff
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @author Kore Nordmann <mail@kore-nordmann.de>
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/diff
*/
class Parser
{
/**
* @param string $string
* @return Diff[]
*/
public function parse($string)
{
$lines = preg_split('(\r\n|\r|\n)', $string);
$lineCount = count($lines);
$diffs = array();
$diff = null;
$collected = array();
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 ($diff !== null) {
$this->parseFileDiff($diff, $collected);
$diffs[] = $diff;
$collected = array();
}
$diff = new Diff($fromMatch['file'], $toMatch['file']);
++$i;
} else {
if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
continue;
}
$collected[] = $lines[$i];
}
}
if (count($collected) && ($diff !== null)) {
$this->parseFileDiff($diff, $collected);
$diffs[] = $diff;
}
return $diffs;
}
/**
* @param Diff $diff
* @param array $lines
*/
private function parseFileDiff(Diff $diff, array $lines)
{
$chunks = array();
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)) {
$chunk = new Chunk(
$match['start'],
isset($match['startrange']) ? max(1, $match['startrange']) : 1,
$match['end'],
isset($match['endrange']) ? max(1, $match['endrange']) : 1
);
$chunks[] = $chunk;
$diffLines = array();
continue;
}
if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
$type = Line::UNCHANGED;
if ($match['type'] == '+') {
$type = Line::ADDED;
} elseif ($match['type'] == '-') {
$type = Line::REMOVED;
}
$diffLines[] = new Line($type, $match['line']);
if (isset($chunk)) {
$chunk->setLines($diffLines);
}
}
}
$diff->setChunks($chunks);
}
}

View file

@ -0,0 +1,5 @@
/.idea
/vendor
/composer.lock
/composer.phar
/phpunit.xml

View file

@ -0,0 +1,16 @@
language: php
before_script:
- composer self-update
- composer install --no-interaction --prefer-source --dev
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
notifications:
email: false

View file

@ -0,0 +1,33 @@
Environment
Copyright (c) 2014-2015, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,72 @@
# 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)
## 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:
{
"require": {
"sebastian/environment": "1.0.*"
}
}
## 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)

View file

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

View file

@ -0,0 +1,29 @@
{
"name": "sebastian/environment",
"description": "Provides functionality to handle HHVM/PHP environments",
"keywords": ["environment","hhvm","xdebug"],
"homepage": "http://www.github.com/sebastianbergmann/environment",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
}
}
}

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
checkForUnintentionallyCoveredCode="true"
verbose="true">
<testsuites>
<testsuite name="Environment">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory>src</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,81 @@
<?php
/*
* This file is part of the Environment 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\Environment;
/**
*/
class Console
{
const STDIN = 0;
const STDOUT = 1;
const STDERR = 2;
/**
* Returns true if STDOUT supports colorization.
*
* This code has been copied and adapted from
* Symfony\Component\Console\Output\OutputStream.
*
* @return bool
*/
public function hasColorSupport()
{
if (DIRECTORY_SEPARATOR == '\\') {
return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
}
if (!defined('STDOUT')) {
return false;
}
return $this->isInteractive(STDOUT);
}
/**
* Returns the number of columns of the terminal.
*
* @return int
*/
public function getNumberOfColumns()
{
// Windows terminals have a fixed size of 80
// but one column is used for the cursor.
if (DIRECTORY_SEPARATOR == '\\') {
return 79;
}
if (!$this->isInteractive(self::STDIN)) {
return 80;
}
if (preg_match('#\d+ (\d+)#', shell_exec('stty size'), $match) === 1) {
return (int) $match[1];
}
if (preg_match('#columns = (\d+);#', shell_exec('stty'), $match) === 1) {
return (int) $match[1];
}
return 80;
}
/**
* Returns if the file descriptor is an interactive terminal or not.
*
* @param int|resource $fileDescriptor
*
* @return bool
*/
public function isInteractive($fileDescriptor = self::STDOUT)
{
return function_exists('posix_isatty') && @posix_isatty($fileDescriptor);
}
}

View file

@ -0,0 +1,192 @@
<?php
/*
* This file is part of the Environment 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\Environment;
/**
* Utility class for HHVM/PHP environment handling.
*/
class Runtime
{
/**
* @var string
*/
private static $binary;
/**
* Returns true when Xdebug is supported or
* the runtime used is PHPDBG (PHP >= 7.0).
*
* @return bool
*/
public function canCollectCodeCoverage()
{
return $this->hasXdebug() || $this->hasPHPDBGCodeCoverage();
}
/**
* Returns the path to the binary of the current runtime.
* Appends ' --php' to the path when the runtime is HHVM.
*
* @return string
*/
public function getBinary()
{
// HHVM
if (self::$binary === null && $this->isHHVM()) {
if ((self::$binary = getenv('PHP_BINARY')) === false) {
self::$binary = PHP_BINARY;
}
self::$binary = escapeshellarg(self::$binary) . ' --php';
}
// PHP >= 5.4.0
if (self::$binary === null && defined('PHP_BINARY')) {
self::$binary = escapeshellarg(PHP_BINARY);
}
// PHP < 5.4.0
if (self::$binary === null) {
if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
if (strpos($_SERVER['_'], 'phpunit') !== false) {
$file = file($_SERVER['_']);
if (strpos($file[0], ' ') !== false) {
$tmp = explode(' ', $file[0]);
self::$binary = escapeshellarg(trim($tmp[1]));
} else {
self::$binary = escapeshellarg(ltrim(trim($file[0]), '#!'));
}
} elseif (strpos(basename($_SERVER['_']), 'php') !== false) {
self::$binary = escapeshellarg($_SERVER['_']);
}
}
}
if (self::$binary === null) {
$possibleBinaryLocations = array(
PHP_BINDIR . '/php',
PHP_BINDIR . '/php-cli.exe',
PHP_BINDIR . '/php.exe'
);
foreach ($possibleBinaryLocations as $binary) {
if (is_readable($binary)) {
self::$binary = escapeshellarg($binary);
break;
}
}
}
if (self::$binary === null) {
self::$binary = 'php';
}
return self::$binary;
}
/**
* @return string
*/
public function getNameWithVersion()
{
return $this->getName() . ' ' . $this->getVersion();
}
/**
* @return string
*/
public function getName()
{
if ($this->isHHVM()) {
return 'HHVM';
} elseif ($this->isPHPDBG()) {
return 'PHPDBG';
} else {
return 'PHP';
}
}
/**
* @return string
*/
public function getVendorUrl()
{
if ($this->isHHVM()) {
return 'http://hhvm.com/';
} else {
return 'http://php.net/';
}
}
/**
* @return string
*/
public function getVersion()
{
if ($this->isHHVM()) {
return HHVM_VERSION;
} else {
return PHP_VERSION;
}
}
/**
* Returns true when the runtime used is PHP and Xdebug is loaded.
*
* @return bool
*/
public function hasXdebug()
{
return ($this->isPHP() || $this->isHHVM()) && extension_loaded('xdebug');
}
/**
* Returns true when the runtime used is HHVM.
*
* @return bool
*/
public function isHHVM()
{
return defined('HHVM_VERSION');
}
/**
* Returns true when the runtime used is PHP without the PHPDBG SAPI.
*
* @return bool
*/
public function isPHP()
{
return !$this->isHHVM() && !$this->isPHPDBG();
}
/**
* Returns true when the runtime used is PHP with the PHPDBG SAPI.
*
* @return bool
*/
public function isPHPDBG()
{
return PHP_SAPI === 'phpdbg' && !$this->isHHVM();
}
/**
* Returns true when the runtime used is PHP with the PHPDBG SAPI
* and the phpdbg_*_oplog() functions are available (PHP >= 7.0).
*
* @return bool
*/
public function hasPHPDBGCodeCoverage()
{
return $this->isPHPDBG() && function_exists('phpdbg_start_oplog');
}
}

View file

@ -0,0 +1,9 @@
.idea
phpunit.xml
composer.lock
composer.phar
vendor/
cache.properties
build/LICENSE
build/README.md
build/*.tgz

View file

@ -0,0 +1,23 @@
language: php
before_script:
- composer self-update
- composer install --no-interaction --prefer-source --dev
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
notifications:
email: false
webhooks:
urls:
- https://webhooks.gitter.im/e/6668f52f3dd4e3f81960
on_success: always
on_failure: always
on_start: false

33
web/vendor/sebastian/exporter/LICENSE vendored Normal file
View file

@ -0,0 +1,33 @@
Exporter
Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

171
web/vendor/sebastian/exporter/README.md vendored Normal file
View file

@ -0,0 +1,171 @@
Exporter
========
[![Build Status](https://secure.travis-ci.org/sebastianbergmann/exporter.png?branch=master)](https://travis-ci.org/sebastianbergmann/exporter)
This component provides the functionality to export PHP variables for visualization.
## Usage
Exporting:
```php
<?php
use SebastianBergmann\Exporter\Exporter;
$exporter = new Exporter;
/*
Exception Object &0000000078de0f0d000000002003a261 (
'message' => ''
'string' => ''
'code' => 0
'file' => '/home/sebastianbergmann/test.php'
'line' => 34
'trace' => Array &0 ()
'previous' => null
)
*/
print $exporter->export(new Exception);
```
## Data Types
Exporting simple types:
```php
<?php
use SebastianBergmann\Exporter\Exporter;
$exporter = new Exporter;
// 46
print $exporter->export(46);
// 4.0
print $exporter->export(4.0);
// 'hello, world!'
print $exporter->export('hello, world!');
// false
print $exporter->export(false);
// NAN
print $exporter->export(acos(8));
// -INF
print $exporter->export(log(0));
// null
print $exporter->export(null);
// resource(13) of type (stream)
print $exporter->export(fopen('php://stderr', 'w'));
// Binary String: 0x000102030405
print $exporter->export(chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5));
```
Exporting complex types:
```php
<?php
use SebastianBergmann\Exporter\Exporter;
$exporter = new Exporter;
/*
Array &0 (
0 => Array &1 (
0 => 1
1 => 2
2 => 3
)
1 => Array &2 (
0 => ''
1 => 0
2 => false
)
)
*/
print $exporter->export(array(array(1,2,3), array("",0,FALSE)));
/*
Array &0 (
'self' => Array &1 (
'self' => Array &1
)
)
*/
$array = array();
$array['self'] = &$array;
print $exporter->export($array);
/*
stdClass Object &0000000003a66dcc0000000025e723e2 (
'self' => stdClass Object &0000000003a66dcc0000000025e723e2
)
*/
$obj = new stdClass();
$obj->self = $obj;
print $exporter->export($obj);
```
Compact exports:
```php
<?php
use SebastianBergmann\Exporter\Exporter;
$exporter = new Exporter;
// Array ()
print $exporter->shortenedExport(array());
// Array (...)
print $exporter->shortenedExport(array(1,2,3,4,5));
// stdClass Object ()
print $exporter->shortenedExport(new stdClass);
// Exception Object (...)
print $exporter->shortenedExport(new Exception);
// this\nis\na\nsuper\nlong\nstring\nt...\nspace
print $exporter->shortenedExport(
<<<LONG_STRING
this
is
a
super
long
string
that
wraps
a
lot
and
eats
up
a
lot
of
space
LONG_STRING
);
```
## Installation
To add Exporter as a local, per-project dependency to your project, simply add a dependency on `sebastian/exporter` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Exporter 1.0:
{
"require": {
"sebastian/exporter": "1.0.*"
}
}

27
web/vendor/sebastian/exporter/build.xml vendored Normal file
View file

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

View file

@ -0,0 +1,47 @@
{
"name": "sebastian/exporter",
"description": "Provides the functionality to export PHP variables for visualization",
"keywords": ["exporter","export"],
"homepage": "http://www.github.com/sebastianbergmann/exporter",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
}
],
"require": {
"php": ">=5.3.3",
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
}
}

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
bootstrap="vendor/autoload.php"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
checkForUnintentionallyCoveredCode="true"
forceCoversAnnotation="true"
verbose="true">
<testsuites>
<testsuite name="exporter">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
<directory>src</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,296 @@
<?php
/*
* This file is part of the Exporter 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\Exporter;
use SebastianBergmann\RecursionContext\Context;
/**
* A nifty utility for visualizing PHP variables.
*
* <code>
* <?php
* use SebastianBergmann\Exporter\Exporter;
*
* $exporter = new Exporter;
* print $exporter->export(new Exception);
* </code>
*/
class Exporter
{
/**
* Exports a value as a string
*
* The output of this method is similar to the output of print_r(), but
* improved in various aspects:
*
* - NULL is rendered as "null" (instead of "")
* - TRUE is rendered as "true" (instead of "1")
* - FALSE is rendered as "false" (instead of "")
* - Strings are always quoted with single quotes
* - Carriage returns and newlines are normalized to \n
* - Recursion and repeated rendering is treated properly
*
* @param mixed $value
* @param int $indentation The indentation level of the 2nd+ line
* @return string
*/
public function export($value, $indentation = 0)
{
return $this->recursiveExport($value, $indentation);
}
/**
* @param mixed $data
* @param Context $context
* @return string
*/
public function shortenedRecursiveExport(&$data, Context $context = null)
{
$result = array();
$exporter = new self();
if (!$context) {
$context = new Context;
}
$context->add($data);
foreach ($data as $key => $value) {
if (is_array($value)) {
if ($context->contains($data[$key]) !== false) {
$result[] = '*RECURSION*';
}
else {
$result[] = sprintf(
'array(%s)',
$this->shortenedRecursiveExport($data[$key], $context)
);
}
}
else {
$result[] = $exporter->shortenedExport($value);
}
}
return implode(', ', $result);
}
/**
* Exports a value into a single-line string
*
* The output of this method is similar to the output of
* SebastianBergmann\Exporter\Exporter::export. This method guarantees
* thought that the result contains now newlines.
*
* Newlines are replaced by the visible string '\n'. Contents of arrays
* and objects (if any) are replaced by '...'.
*
* @param mixed $value
* @return string
* @see SebastianBergmann\Exporter\Exporter::export
*/
public function shortenedExport($value)
{
if (is_string($value)) {
$string = $this->export($value);
if (strlen($string) > 40) {
$string = substr($string, 0, 30) . '...' . substr($string, -7);
}
return str_replace("\n", '\n', $string);
}
if (is_object($value)) {
return sprintf(
'%s Object (%s)',
get_class($value),
count($this->toArray($value)) > 0 ? '...' : ''
);
}
if (is_array($value)) {
return sprintf(
'Array (%s)',
count($value) > 0 ? '...' : ''
);
}
return $this->export($value);
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param mixed $value
* @return array
*/
public function toArray($value)
{
if (!is_object($value)) {
return (array) $value;
}
$array = array();
foreach ((array) $value as $key => $val) {
// properties are transformed to keys in the following way:
// private $property => "\0Classname\0property"
// protected $property => "\0*\0property"
// public $property => "property"
if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) {
$key = $matches[1];
}
// See https://github.com/php/php-src/commit/5721132
if ($key === "\0gcdata") {
continue;
}
$array[$key] = $val;
}
// Some internal classes like SplObjectStorage don't work with the
// above (fast) mechanism nor with reflection in Zend.
// Format the output similarly to print_r() in this case
if ($value instanceof \SplObjectStorage) {
// However, the fast method does work in HHVM, and exposes the
// internal implementation. Hide it again.
if (property_exists('\SplObjectStorage', '__storage')) {
unset($array['__storage']);
} elseif (property_exists('\SplObjectStorage', 'storage')) {
unset($array['storage']);
}
if (property_exists('\SplObjectStorage', '__key')) {
unset($array['__key']);
}
foreach ($value as $key => $val) {
$array[spl_object_hash($val)] = array(
'obj' => $val,
'inf' => $value->getInfo(),
);
}
}
return $array;
}
/**
* Recursive implementation of export
*
* @param mixed $value The value to export
* @param int $indentation The indentation level of the 2nd+ line
* @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects
* @return string
* @see SebastianBergmann\Exporter\Exporter::export
*/
protected function recursiveExport(&$value, $indentation, $processed = null)
{
if ($value === null) {
return 'null';
}
if ($value === true) {
return 'true';
}
if ($value === false) {
return 'false';
}
if (is_float($value) && floatval(intval($value)) === $value) {
return "$value.0";
}
if (is_resource($value)) {
return sprintf(
'resource(%d) of type (%s)',
$value,
get_resource_type($value)
);
}
if (is_string($value)) {
// Match for most non printable chars somewhat taking multibyte chars into account
if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) {
return 'Binary String: 0x' . bin2hex($value);
}
return "'" .
str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) .
"'";
}
$whitespace = str_repeat(' ', 4 * $indentation);
if (!$processed) {
$processed = new Context;
}
if (is_array($value)) {
if (($key = $processed->contains($value)) !== false) {
return 'Array &' . $key;
}
$key = $processed->add($value);
$values = '';
if (count($value) > 0) {
foreach ($value as $k => $v) {
$values .= sprintf(
'%s %s => %s' . "\n",
$whitespace,
$this->recursiveExport($k, $indentation),
$this->recursiveExport($value[$k], $indentation + 1, $processed)
);
}
$values = "\n" . $values . $whitespace;
}
return sprintf('Array &%s (%s)', $key, $values);
}
if (is_object($value)) {
$class = get_class($value);
if ($hash = $processed->contains($value)) {
return sprintf('%s Object &%s', $class, $hash);
}
$hash = $processed->add($value);
$values = '';
$array = $this->toArray($value);
if (count($array) > 0) {
foreach ($array as $k => $v) {
$values .= sprintf(
'%s %s => %s' . "\n",
$whitespace,
$this->recursiveExport($k, $indentation),
$this->recursiveExport($v, $indentation + 1, $processed)
);
}
$values = "\n" . $values . $whitespace;
}
return sprintf('%s Object &%s (%s)', $class, $hash, $values);
}
return var_export($value, true);
}
}

View file

@ -0,0 +1,5 @@
.idea
composer.lock
composer.phar
vendor/
cache.properties

View file

@ -0,0 +1,19 @@
language: php
before_script:
- composer self-update
- composer install --no-interaction --prefer-source --dev
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
script: ./vendor/bin/phpunit --configuration ./build/phpunit.xml
notifications:
email: false
irc: "irc.freenode.org#phpunit"

View file

@ -0,0 +1,33 @@
GlobalState
Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,13 @@
# GlobalState
Snapshotting of global state, 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/global-state` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on GlobalState:
{
"require": {
"sebastian/global-state": "1.0.*"
}
}

View file

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

View file

@ -0,0 +1,16 @@
<?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="GlobalState">
<directory suffix="Test.php">../tests</directory>
</testsuite>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../src</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,37 @@
{
"name": "sebastian/global-state",
"description": "Snapshotting of global state",
"keywords": ["global state"],
"homepage": "http://www.github.com/sebastianbergmann/global-state",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"suggest": {
"ext-uopz": "*"
},
"autoload": {
"classmap": [
"src/"
]
},
"autoload-dev": {
"classmap": [
"tests/_fixture/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
}
}

View file

@ -0,0 +1,186 @@
<?php
/**
* GlobalState
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
namespace SebastianBergmann\GlobalState;
use ReflectionClass;
/**
* A blacklist for global state elements that should not be snapshotted.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
class Blacklist
{
/**
* @var array
*/
private $globalVariables = array();
/**
* @var array
*/
private $classes = array();
/**
* @var array
*/
private $classNamePrefixes = array();
/**
* @var array
*/
private $parentClasses = array();
/**
* @var array
*/
private $interfaces = array();
/**
* @var array
*/
private $staticAttributes = array();
/**
* @param string $variableName
*/
public function addGlobalVariable($variableName)
{
$this->globalVariables[$variableName] = true;
}
/**
* @param string $className
*/
public function addClass($className)
{
$this->classes[] = $className;
}
/**
* @param string $className
*/
public function addSubclassesOf($className)
{
$this->parentClasses[] = $className;
}
/**
* @param string $interfaceName
*/
public function addImplementorsOf($interfaceName)
{
$this->interfaces[] = $interfaceName;
}
/**
* @param string $classNamePrefix
*/
public function addClassNamePrefix($classNamePrefix)
{
$this->classNamePrefixes[] = $classNamePrefix;
}
/**
* @param string $className
* @param string $attributeName
*/
public function addStaticAttribute($className, $attributeName)
{
if (!isset($this->staticAttributes[$className])) {
$this->staticAttributes[$className] = array();
}
$this->staticAttributes[$className][$attributeName] = true;
}
/**
* @param string $variableName
* @return boolean
*/
public function isGlobalVariableBlacklisted($variableName)
{
return isset($this->globalVariables[$variableName]);
}
/**
* @param string $className
* @param string $attributeName
* @return boolean
*/
public function isStaticAttributeBlacklisted($className, $attributeName)
{
if (in_array($className, $this->classes)) {
return true;
}
foreach ($this->classNamePrefixes as $prefix) {
if (strpos($className, $prefix) === 0) {
return true;
}
}
$class = new ReflectionClass($className);
foreach ($this->parentClasses as $type) {
if ($class->isSubclassOf($type)) {
return true;
}
}
foreach ($this->interfaces as $type) {
if ($class->implementsInterface($type)) {
return true;
}
}
if (isset($this->staticAttributes[$className][$attributeName])) {
return true;
}
return false;
}
}

View file

@ -0,0 +1,53 @@
<?php
/**
* GlobalState
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
namespace SebastianBergmann\GlobalState;
/**
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
interface Exception
{
}

View file

@ -0,0 +1,150 @@
<?php
/**
* GlobalState
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
namespace SebastianBergmann\GlobalState;
use ReflectionProperty;
/**
* Restorer of snapshots of global state.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
class Restorer
{
/**
* Deletes function definitions that are not defined in a snapshot.
*
* @param Snapshot $snapshot
* @throws RuntimeException when the uopz_delete() function is not available
* @see https://github.com/krakjoe/uopz
*/
public function restoreFunctions(Snapshot $snapshot)
{
if (!function_exists('uopz_delete')) {
throw new RuntimeException('The uopz_delete() function is required for this operation');
}
$functions = get_defined_functions();
foreach (array_diff($functions['user'], $snapshot->functions()) as $function) {
uopz_delete($function);
}
}
/**
* Restores all global and super-global variables from a snapshot.
*
* @param Snapshot $snapshot
*/
public function restoreGlobalVariables(Snapshot $snapshot)
{
$superGlobalArrays = $snapshot->superGlobalArrays();
foreach ($superGlobalArrays as $superGlobalArray) {
$this->restoreSuperGlobalArray($snapshot, $superGlobalArray);
}
$globalVariables = $snapshot->globalVariables();
foreach (array_keys($GLOBALS) as $key) {
if ($key != 'GLOBALS' &&
!in_array($key, $superGlobalArrays) &&
!$snapshot->blacklist()->isGlobalVariableBlacklisted($key)) {
if (isset($globalVariables[$key])) {
$GLOBALS[$key] = $globalVariables[$key];
} else {
unset($GLOBALS[$key]);
}
}
}
}
/**
* Restores all static attributes in user-defined classes from this snapshot.
*
* @param Snapshot $snapshot
*/
public function restoreStaticAttributes(Snapshot $snapshot)
{
foreach ($snapshot->staticAttributes() as $className => $staticAttributes) {
foreach ($staticAttributes as $name => $value) {
$reflector = new ReflectionProperty($className, $name);
$reflector->setAccessible(true);
$reflector->setValue($value);
}
}
}
/**
* Restores a super-global variable array from this snapshot.
*
* @param Snapshot $snapshot
* @param $superGlobalArray
*/
private function restoreSuperGlobalArray(Snapshot $snapshot, $superGlobalArray)
{
$superGlobalVariables = $snapshot->superGlobalVariables();
if (isset($GLOBALS[$superGlobalArray]) &&
is_array($GLOBALS[$superGlobalArray]) &&
isset($superGlobalVariables[$superGlobalArray])) {
$keys = array_keys(
array_merge(
$GLOBALS[$superGlobalArray],
$superGlobalVariables[$superGlobalArray]
)
);
foreach ($keys as $key) {
if (isset($superGlobalVariables[$superGlobalArray][$key])) {
$GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key];
} else {
unset($GLOBALS[$superGlobalArray][$key]);
}
}
}
}
}

View file

@ -0,0 +1,53 @@
<?php
/**
* GlobalState
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
namespace SebastianBergmann\GlobalState;
/**
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
class RuntimeException extends \RuntimeException implements Exception
{
}

View file

@ -0,0 +1,443 @@
<?php
/**
* GlobalState
*
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Sebastian Bergmann nor the names of his
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
namespace SebastianBergmann\GlobalState;
use Closure;
use ReflectionClass;
/**
* A snapshot of global state.
*
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/sebastianbergmann/global-state
*/
class Snapshot
{
/**
* @var Blacklist
*/
private $blacklist;
/**
* @var array
*/
private $globalVariables = array();
/**
* @var array
*/
private $superGlobalArrays = array();
/**
* @var array
*/
private $superGlobalVariables = array();
/**
* @var array
*/
private $staticAttributes = array();
/**
* @var array
*/
private $iniSettings = array();
/**
* @var array
*/
private $includedFiles = array();
/**
* @var array
*/
private $constants = array();
/**
* @var array
*/
private $functions = array();
/**
* @var array
*/
private $interfaces = array();
/**
* @var array
*/
private $classes = array();
/**
* @var array
*/
private $traits = array();
/**
* Creates a snapshot of the current global state.
*
* @param Blacklist $blacklist
* @param boolean $includeGlobalVariables
* @param boolean $includeStaticAttributes
* @param boolean $includeConstants
* @param boolean $includeFunctions
* @param boolean $includeClasses
* @param boolean $includeInterfaces
* @param boolean $includeTraits
* @param boolean $includeIniSettings
* @param boolean $includeIncludedFiles
*/
public function __construct(Blacklist $blacklist = null, $includeGlobalVariables = true, $includeStaticAttributes = true, $includeConstants = true, $includeFunctions = true, $includeClasses = true, $includeInterfaces = true, $includeTraits = true, $includeIniSettings = true, $includeIncludedFiles = true)
{
if ($blacklist === null) {
$blacklist = new Blacklist;
}
$this->blacklist = $blacklist;
if ($includeConstants) {
$this->snapshotConstants();
}
if ($includeFunctions) {
$this->snapshotFunctions();
}
if ($includeClasses || $includeStaticAttributes) {
$this->snapshotClasses();
}
if ($includeInterfaces) {
$this->snapshotInterfaces();
}
if ($includeGlobalVariables) {
$this->setupSuperGlobalArrays();
$this->snapshotGlobals();
}
if ($includeStaticAttributes) {
$this->snapshotStaticAttributes();
}
if ($includeIniSettings) {
$this->iniSettings = ini_get_all(null, false);
}
if ($includeIncludedFiles) {
$this->includedFiles = get_included_files();
}
if (function_exists('get_declared_traits')) {
$this->traits = get_declared_traits();
}
}
/**
* @return Blacklist
*/
public function blacklist()
{
return $this->blacklist;
}
/**
* @return array
*/
public function globalVariables()
{
return $this->globalVariables;
}
/**
* @return array
*/
public function superGlobalVariables()
{
return $this->superGlobalVariables;
}
/**
* Returns a list of all super-global variable arrays.
*
* @return array
*/
public function superGlobalArrays()
{
return $this->superGlobalArrays;
}
/**
* @return array
*/
public function staticAttributes()
{
return $this->staticAttributes;
}
/**
* @return array
*/
public function iniSettings()
{
return $this->iniSettings;
}
/**
* @return array
*/
public function includedFiles()
{
return $this->includedFiles;
}
/**
* @return array
*/
public function constants()
{
return $this->constants;
}
/**
* @return array
*/
public function functions()
{
return $this->functions;
}
/**
* @return array
*/
public function interfaces()
{
return $this->interfaces;
}
/**
* @return array
*/
public function classes()
{
return $this->classes;
}
/**
* @return array
*/
public function traits()
{
return $this->traits;
}
/**
* Creates a snapshot user-defined constants.
*/
private function snapshotConstants()
{
$constants = get_defined_constants(true);
if (isset($constants['user'])) {
$this->constants = $constants['user'];
}
}
/**
* Creates a snapshot user-defined functions.
*/
private function snapshotFunctions()
{
$functions = get_defined_functions();
$this->functions = $functions['user'];
}
/**
* Creates a snapshot user-defined classes.
*/
private function snapshotClasses()
{
foreach (array_reverse(get_declared_classes()) as $className) {
$class = new ReflectionClass($className);
if (!$class->isUserDefined()) {
break;
}
$this->classes[] = $className;
}
$this->classes = array_reverse($this->classes);
}
/**
* Creates a snapshot user-defined interfaces.
*/
private function snapshotInterfaces()
{
foreach (array_reverse(get_declared_interfaces()) as $interfaceName) {
$class = new ReflectionClass($interfaceName);
if (!$class->isUserDefined()) {
break;
}
$this->interfaces[] = $interfaceName;
}
$this->interfaces = array_reverse($this->interfaces);
}
/**
* Creates a snapshot of all global and super-global variables.
*/
private function snapshotGlobals()
{
$superGlobalArrays = $this->superGlobalArrays();
foreach ($superGlobalArrays as $superGlobalArray) {
$this->snapshotSuperGlobalArray($superGlobalArray);
}
foreach (array_keys($GLOBALS) as $key) {
if ($key != 'GLOBALS' &&
!in_array($key, $superGlobalArrays) &&
$this->canBeSerialized($GLOBALS[$key]) &&
!$this->blacklist->isGlobalVariableBlacklisted($key)) {
$this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
}
}
}
/**
* Creates a snapshot a super-global variable array.
*
* @param $superGlobalArray
*/
private function snapshotSuperGlobalArray($superGlobalArray)
{
$this->superGlobalVariables[$superGlobalArray] = array();
if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
$this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
}
}
}
/**
* Creates a snapshot of all static attributes in user-defined classes.
*/
private function snapshotStaticAttributes()
{
foreach ($this->classes as $className) {
$class = new ReflectionClass($className);
$snapshot = array();
foreach ($class->getProperties() as $attribute) {
if ($attribute->isStatic()) {
$name = $attribute->getName();
if ($this->blacklist->isStaticAttributeBlacklisted($className, $name)) {
continue;
}
$attribute->setAccessible(true);
$value = $attribute->getValue();
if ($this->canBeSerialized($value)) {
$snapshot[$name] = unserialize(serialize($value));
}
}
}
if (!empty($snapshot)) {
$this->staticAttributes[$className] = $snapshot;
}
}
}
/**
* Returns a list of all super-global variable arrays.
*
* @return array
*/
private function setupSuperGlobalArrays()
{
$this->superGlobalArrays = array(
'_ENV',
'_POST',
'_GET',
'_COOKIE',
'_SERVER',
'_FILES',
'_REQUEST'
);
if (ini_get('register_long_arrays') == '1') {
$this->superGlobalArrays = array_merge(
$this->superGlobalArrays,
array(
'HTTP_ENV_VARS',
'HTTP_POST_VARS',
'HTTP_GET_VARS',
'HTTP_COOKIE_VARS',
'HTTP_SERVER_VARS',
'HTTP_POST_FILES'
)
);
}
}
/**
* @param mixed $variable
* @return boolean
* @todo Implement this properly
*/
private function canBeSerialized($variable) {
return !$variable instanceof Closure;
}
}

View file

@ -0,0 +1,9 @@
.idea
phpunit.xml
composer.lock
composer.phar
vendor/
cache.properties
build/LICENSE
build/README.md
build/*.tgz

View file

@ -0,0 +1,21 @@
language: php
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
sudo: false
before_script:
- composer self-update
- composer install --no-interaction --prefer-source --dev
script: ./vendor/bin/phpunit
notifications:
email: false
irc: "irc.freenode.org#phpunit"

View file

@ -0,0 +1,33 @@
Recursion Context
Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,13 @@
# Recursion Context
...
## Installation
To add Recursion Context as a local, per-project dependency to your project, simply add a dependency on `sebastian/recursion-context` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Recursion Context 1.0:
{
"require": {
"sebastian/recursion-context": "~1.0"
}
}

View file

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

View file

@ -0,0 +1,36 @@
{
"name": "sebastian/recursion-context",
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
bootstrap="vendor/autoload.php"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
checkForUnintentionallyCoveredCode="true"
forceCoversAnnotation="true"
verbose="true">
<testsuites>
<testsuite name="recursion-context">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
<directory>src</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,153 @@
<?php
/*
* This file is part of the Recursion Context 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\RecursionContext;
/**
* A context containing previously processed arrays and objects
* when recursively processing a value.
*/
final class Context
{
/**
* @var array[]
*/
private $arrays;
/**
* @var \SplObjectStorage
*/
private $objects;
/**
* Initialises the context
*/
public function __construct()
{
$this->arrays = array();
$this->objects = new \SplObjectStorage;
}
/**
* Adds a value to the context.
*
* @param array|object $value The value to add.
* @return int|string The ID of the stored value, either as
* a string or integer.
* @throws InvalidArgumentException Thrown if $value is not an array or
* object
*/
public function add(&$value)
{
if (is_array($value)) {
return $this->addArray($value);
}
else if (is_object($value)) {
return $this->addObject($value);
}
throw new InvalidArgumentException(
'Only arrays and objects are supported'
);
}
/**
* Checks if the given value exists within the context.
*
* @param array|object $value The value to check.
* @return int|string|false The string or integer ID of the stored
* value if it has already been seen, or
* false if the value is not stored.
* @throws InvalidArgumentException Thrown if $value is not an array or
* object
*/
public function contains(&$value)
{
if (is_array($value)) {
return $this->containsArray($value);
}
else if (is_object($value)) {
return $this->containsObject($value);
}
throw new InvalidArgumentException(
'Only arrays and objects are supported'
);
}
/**
* @param array $array
* @return bool|int
*/
private function addArray(array &$array)
{
$key = $this->containsArray($array);
if ($key !== false) {
return $key;
}
$this->arrays[] = &$array;
return count($this->arrays) - 1;
}
/**
* @param object $object
* @return string
*/
private function addObject($object)
{
if (!$this->objects->contains($object)) {
$this->objects->attach($object);
}
return spl_object_hash($object);
}
/**
* @param array $array
* @return int|false
*/
private function containsArray(array &$array)
{
$keys = array_keys($this->arrays, $array, true);
$hash = '_Key_' . hash('sha512', microtime(true));
foreach ($keys as $key) {
$this->arrays[$key][$hash] = $hash;
if (isset($array[$hash]) && $array[$hash] === $hash) {
unset($this->arrays[$key][$hash]);
return $key;
}
unset($this->arrays[$key][$hash]);
}
return false;
}
/**
* @param object $value
* @return string|false
*/
private function containsObject($value)
{
if ($this->objects->contains($value)) {
return spl_object_hash($value);
}
return false;
}
}

View file

@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Recursion Context 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\RecursionContext;
/**
*/
interface Exception
{
}

View file

@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Recursion Context 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\RecursionContext;
/**
*/
final class InvalidArgumentException extends \InvalidArgumentException implements Exception
{
}

View file

@ -0,0 +1 @@
*.php diff=php

View file

@ -0,0 +1 @@
/.idea

33
web/vendor/sebastian/version/LICENSE vendored Normal file
View file

@ -0,0 +1,33 @@
Version
Copyright (c) 2013-2015, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

37
web/vendor/sebastian/version/README.md vendored Normal file
View file

@ -0,0 +1,37 @@
# Version
**Version** is a library that helps with managing the version number of Git-hosted PHP projects.
## Installation
Simply add a dependency on `sebastian/version` to your project's `composer.json` file if you use [Composer](http://getcomposer.org/) to manage the dependencies of your project.
## Usage
The constructor of the `SebastianBergmann\Version` class expects two parameters:
* `$release` is the version number of the latest release (`X.Y.Z`, for instance) or the name of the release series (`X.Y`) when no release has been made from that branch / for that release series yet.
* `$path` is the path to the directory (or a subdirectory thereof) where the sourcecode of the project can be found. Simply passing `__DIR__` here usually suffices.
Apart from the constructor, the `SebastianBergmann\Version` class has a single public method: `getVersion()`.
Here is a contrived example that shows the basic usage:
<?php
$version = new SebastianBergmann\Version(
'3.7.10', '/usr/local/src/phpunit'
);
var_dump($version->getVersion());
?>
string(18) "3.7.10-17-g00f3408"
When a new release is prepared, the string that is passed to the constructor as the first argument needs to be updated.
### How SebastianBergmann\Version::getVersion() works
* If `$path` is not (part of) a Git repository and `$release` is in `X.Y.Z` format then `$release` is returned as-is.
* If `$path` is not (part of) a Git repository and `$release` is in `X.Y` format then `$release` is returned suffixed with `-dev`.
* If `$path` is (part of) a Git repository and `$release` is in `X.Y.Z` format then the output of `git describe --tags` is returned as-is.
* If `$path` is (part of) a Git repository and `$release` is in `X.Y` format then a string is returned that begins with `X.Y` and ends with information from `git describe --tags`.

View file

@ -0,0 +1,21 @@
{
"name": "sebastian/version",
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/version/issues"
},
"autoload": {
"classmap": [
"src/"
]
}
}

View file

@ -0,0 +1,82 @@
<?php
/*
* This file is part of the Version 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;
/**
* @since Class available since Release 1.0.0
*/
class Version
{
private $path;
private $release;
private $version;
/**
* @param string $release
* @param string $path
*/
public function __construct($release, $path)
{
$this->release = $release;
$this->path = $path;
}
/**
* @return string
*/
public function getVersion()
{
if ($this->version === null) {
if (count(explode('.', $this->release)) == 3) {
$this->version = $this->release;
} else {
$this->version = $this->release . '-dev';
}
$git = $this->getGitInformation($this->path);
if ($git) {
if (count(explode('.', $this->release)) == 3) {
$this->version = $git;
} else {
$git = explode('-', $git);
$this->version = $this->release . '-' . end($git);
}
}
}
return $this->version;
}
/**
* @param string $path
* @return bool|string
*/
private function getGitInformation($path)
{
if (!is_dir($path . DIRECTORY_SEPARATOR . '.git')) {
return false;
}
$dir = getcwd();
chdir($path);
$returnCode = 1;
$result = @exec('git describe --tags 2>&1', $output, $returnCode);
chdir($dir);
if ($returnCode !== 0) {
return false;
}
return $result;
}
}