It begins.

This commit is contained in:
Jeff Welch 2013-02-04 23:07:53 -05:00
commit e62663cae7
9 changed files with 1130 additions and 0 deletions

4
.gitignore vendored Normal file
View File

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

33
LICENSE Normal file
View File

@ -0,0 +1,33 @@
PHPExporter
Copyright (c) 2002-2013, 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.

198
README.md Normal file
View File

@ -0,0 +1,198 @@
PHPExporter
===========
PHPExporter is a utility for getting textual representations of PHP values.
```php
<?php
require_once __DIR__.'/../vendor/autoload.php';
use PHPExporter\Exporter;
// 46
echo Exporter::export(46);
// 4.0
echo Exporter::export(4.0);
// 'hello, world!'
echo Exporter::export('hello, world!');
// false
echo Exporter::export(false);
// NAN
echo Exporter::export(acos(8));
// -INF
echo Exporter::export(log(0));
// null
echo Exporter::export(null);
// resource(13) of type (stream)
echo Exporter::export(fopen('php://stderr', 'w'));
/*
Array &0 (
0 => Array &1 (
0 => 1
1 => 2
2 => 3
)
1 => Array &2 (
0 => ''
1 => 0
2 => false
)
)
*/
echo Exporter::export(array(array(1,2,3), array("",0,FALSE)));
// Array with references
// ----------------------
$array = array();
$array['self'] = &$array;
echo Exporter::export($array);
/*
Array &0 (
'self' => Array &1 (
'self' => Array &1
)
)
*/
// Object with references
// ----------------------
$obj = new stdClass();
$obj->self = $obj;
echo Exporter::export($obj);
/*
stdClass Object &0000000003a66dcc0000000025e723e2 (
'self' => stdClass Object &0000000003a66dcc0000000025e723e2
)
*/
// Kitchen Sink
// ------------
$obj2 = new stdClass;
$obj2->foo = 'bar';
$obj = new stdClass;
$obj->null = NULL;
$obj->boolean = TRUE;
$obj->integer = 1;
$obj->double = 1.2;
$obj->string = '1';
$obj->text = "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext";
$obj->object = $obj2;
$obj->objectagain = $obj2;
$obj->array = array('foo' => 'bar');
$obj->self = $obj;
$array = array(
0 => 0,
'null' => NULL,
'boolean' => TRUE,
'integer' => 1,
'double' => 1.2,
'string' => '1',
'text' => "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext",
'object' => $obj2,
'objectagain' => $obj2,
'array' => array('foo' => 'bar'),
);
$array['self'] = &$array;
echo Exporter::export($array);
/*
Array &0 (
0 => 0
'null' => null
'boolean' => true
'integer' => 1
'double' => 1.2
'string' => '1'
'text' => 'this
is
a
very
very
very
very
very
very
long
text'
'object' => stdClass Object &000000007ed49b01000000006907e890 (
'foo' => 'bar'
)
'objectagain' => stdClass Object &000000007ed49b01000000006907e890
'array' => Array &1 (
'foo' => 'bar'
)
'self' => Array &2 (
0 => 0
'null' => null
'boolean' => true
'integer' => 1
'double' => 1.2
'string' => '1'
'text' => 'this
is
a
very
very
very
very
very
very
long
text'
'object' => stdClass Object &000000007ed49b01000000006907e890
'objectagain' => stdClass Object &000000007ed49b01000000006907e890
'array' => Array &3 (
'foo' => 'bar'
)
'self' => Array &2
)
)
*/
```
PHPExporter works with PHP 5.3.3 or later.
## Installation
The recommended way to install PHPExporter is [through
composer](http://getcomposer.org). Just create a `composer.json` file and
run the `php composer.phar install` command to install it:
{
"require": {
"phpexporter/phpexporter": "1.0.*@dev"
}
}
## Tests
To run the test suite, you need [composer](http://getcomposer.org).
$ php composer.phar install --dev
$ phpunit
## Acknowledgements
This utility was adapted from the
[PHPUnit](https://github.com/sebastianbergmann/phpunit/) project. A special
thanks goes to the following people for their contributions:
* [sebastianbergmann](https://github.com/sebastianbergmann)
* [edorian](https://github.com/edorian)
* [LawnGnome](https://github.com/LawnGnome)
* [bschussek](https://github.com/bschussek)
## License
PHPExporter is licensed under the BSD 3-Clause license.

43
composer.json Normal file
View File

@ -0,0 +1,43 @@
{
"name": "phpexporter/phpexporter",
"description": "Textual representations of PHP values (Adapted from PHPUnit_Util_Type)",
"keywords": ["exporter"],
"homepage": "http://www.github.com/whatthejeff/PHPExporter",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"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"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": { "PHPExporter": "src/" }
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

24
phpunit.xml.dist Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="PHPExporter Test Suite">
<directory>./tests/PHPExporter/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./src</directory>
</whitelist>
</filter>
</phpunit>

View File

@ -0,0 +1,277 @@
<?php
/**
* PHPExporter
*
* Copyright (c) 2001-2013, 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.
*
* @package PHPExporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
namespace PHPExporter;
/**
* Textual representations of PHP values (Adapted from PHPUnit_Util_Type).
*
* @package PHPExporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
class Exporter
{
/**
* Exports a value into 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 The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @return string
*/
public static function export($value, $indentation = 0)
{
return self::recursiveExport($value, $indentation);
}
/**
* Recursive implementation of export
*
* @param mixed $value The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @param PHPExporter\ExporterContext $processed Contains all objects
* and arrays that have
* previously been
* rendered
* @return string
* @see PHPExporter\Exporter::export
*/
protected static 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 ExporterContext;
}
if (is_array($value)) {
if (($key = $processed->contains($value)) !== false) {
return "Array &$key";
}
$key = $processed->add($value);
if (count($value) > 0) {
$output = "Array &$key (\n";
foreach ($value as $k => $v) {
$ek = self::export($k);
$output .= "$whitespace $ek => ".self::recursiveExport($value[$k], $indentation + 1, $processed)."\n";
}
return "$output$whitespace)";
} else {
return "Array &$key ()";
}
}
if (is_object($value)) {
$class = get_class($value);
if ($hash = $processed->contains($value)) {
return "$class Object &$hash";
}
$hash = $processed->add($value);
$array = self::toArray($value);
if (count($array) > 0) {
$output = "$class Object &$hash (\n";
foreach ($array as $k => $v) {
$k = self::export($k);
$output .= "$whitespace $k => ".self::recursiveExport($v, $indentation + 1, $processed)."\n";
}
return "$output$whitespace)";
} else {
return "$class Object &$hash ()";
}
}
return var_export($value, true);
}
/**
* Exports a value into a single-line string
*
* The output of this method is similar to the output of
* PHPExporter\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 The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @return string
* @see PHPExporter\Exporter::export
*/
public static function shortenedExport($value)
{
if (is_string($value)) {
return self::shortenedString($value);
}
if(is_object($value)) {
return sprintf(
"%s Object (%s)",
get_class($value),
count(self::toArray($value)) > 0 ? '...' : ''
);
}
if (is_array($value)) {
return sprintf(
"Array (%s)",
count($value) > 0 ? '...' : ''
);
}
return self::export($value);
}
/**
* Shortens a string and converts all new lines to '\n'
*
* @param string $string The string to shorten
* @param integer $max The maximum length for the string
* @return string
*/
public static function shortenedString($string, $maxLength = 40)
{
$string = self::export($string);
if (strlen($string) > $maxLength) {
$string = substr($string, 0, $maxLength - 10) . '...' . substr($string, -7);
}
return str_replace("\n", '\n', $string);
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
*/
public static function toArray($object)
{
$array = array();
foreach ((array)$object as $key => $value) {
// 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];
}
$array[$key] = $value;
}
// Some internal classes like SplObjectStorage don't work with the
// above (fast) mechanism nor with reflection
// Format the output similarly to print_r() in this case
if ($object instanceof \SplObjectStorage) {
foreach ($object as $key => $value) {
$array[spl_object_hash($value)] = array(
'obj' => $value,
'inf' => $object->getInfo(),
);
}
}
return $array;
}
}

View File

@ -0,0 +1,187 @@
<?php
/**
* PHPExporter
*
* Copyright (c) 2001-2013, 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.
*
* @package PHPExporter
* @author Adam Harvey <aharvey@php.net>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
namespace PHPExporter;
/**
* A context containing previously rendered arrays and objects when recursively
* exporting a value.
*
* @package PHPExporter
* @author Adam Harvey <aharvey@php.net>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
class ExporterContext {
/**
* Previously seen arrays.
*
* @var array[] $arrays
*/
protected $arrays;
/**
* Previously seen objects.
*
* @var SplObjectStorage $objects
*/
protected $objects;
/** Initialises the context. */
public function __construct()
{
$this->arrays = array();
$this->objects = new \SplObjectStorage;
}
/**
* Adds a value to the export context.
*
* @param mixed $value The value to add.
* @return mixed The ID of the stored value, either as a string or integer.
* @throws PHPExporter\ExporterContext Thrown if $value is not an array or
* object.
*/
public function add(&$value)
{
if (is_array($value)) {
return $this->addArray($value);
} elseif (is_object($value)) {
return $this->addObject($value);
}
throw new ExporterException('Only arrays and objects are supported');
}
/**
* Checks if the given value exists within the context.
*
* @param mixed $value The value to check.
* @return mixed The string or integer ID of the stored value if it has
* already been seen, or boolean false if the value is not
* stored.
* @throws PHPExporter\ExporterContext Thrown if $value is not an array or
* object.
*/
public function contains(&$value)
{
if (is_array($value)) {
return $this->containsArray($value);
} elseif (is_object($value)) {
return $this->containsObject($value);
}
throw new ExporterException('Only arrays and objects are supported');
}
/**
* Stores an array within the context.
*
* @param array $value The value to store.
* @return integer The internal ID of the array.
*/
protected function addArray(array &$value)
{
if (($key = $this->containsArray($value)) !== false) {
return $key;
}
$this->arrays[] = &$value;
return count($this->arrays) - 1;
}
/**
* Stores an object within the context.
*
* @param object $value
* @return string The ID of the object.
*/
protected function addObject($value)
{
if (!$this->objects->contains($value)) {
$this->objects->attach($value);
}
return spl_object_hash($value);
}
/**
* Checks if the given array exists within the context.
*
* @param array $value The array to check.
* @return mixed The integer ID of the array if it exists, or boolean false
* otherwise.
*/
protected function containsArray(array &$value)
{
$keys = array_keys($this->arrays, $value, true);
$gen = '_PHPExporter_Key_'.hash('sha512', microtime(true));
foreach ($keys as $key) {
$this->arrays[$key][$gen] = $gen;
if (isset($value[$gen]) && $value[$gen] === $gen) {
unset($this->arrays[$key][$gen]);
return $key;
}
unset($this->arrays[$key][$gen]);
}
return false;
}
/**
* Checks if the given object exists within the context.
*
* @param object $value The object to check.
* @return mixed The string ID of the object if it exists, or boolean false
* otherwise.
*/
protected function containsObject($value)
{
if ($this->objects->contains($value)) {
return spl_object_hash($value);
}
return false;
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* PHPExporter
*
* Copyright (c) 2001-2013, 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.
*
* @package PHPUnit
* @subpackage Framework
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
namespace PHPExporter;
/**
* Exception for PHPExporter runtime errors.
*
* @package PHPExporter
* @author Sebastian Bergmann <sebastian@phpunit.de>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
class ExporterException extends \RuntimeException
{
}

View File

@ -0,0 +1,306 @@
<?php
/**
* PHPExporter
*
* Copyright (c) 2001-2013, 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.
*
* @package PHPExporter
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
use PHPExporter\Exporter;
/**
*
*
* @package PHPExporter
* @author Bernhard Schussek <bschussek@2bepublished.at>
* @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de>
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://www.github.com/whatthejeff/PHPExporter
*/
class ExporterTest extends PHPUnit_Framework_TestCase
{
/**
* Removes spaces in front newlines
*
* @param string $string
* @return string
*/
public static function trimnl($string)
{
return preg_replace('/[ ]*\n/', "\n", $string);
}
public function exportProvider()
{
$obj2 = new stdClass;
$obj2->foo = 'bar';
$obj = new stdClass;
//@codingStandardsIgnoreStart
$obj->null = NULL;
//@codingStandardsIgnoreEnd
$obj->boolean = TRUE;
$obj->integer = 1;
$obj->double = 1.2;
$obj->string = '1';
$obj->text = "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext";
$obj->object = $obj2;
$obj->objectagain = $obj2;
$obj->array = array('foo' => 'bar');
$obj->self = $obj;
$array = array(
0 => 0,
'null' => NULL,
'boolean' => TRUE,
'integer' => 1,
'double' => 1.2,
'string' => '1',
'text' => "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext",
'object' => $obj2,
'objectagain' => $obj2,
'array' => array('foo' => 'bar'),
);
$array['self'] = &$array;
return array(
array(NULL, 'null'),
array(TRUE, 'true'),
array(1, '1'),
array(1.0, '1.0'),
array(1.2, '1.2'),
array(fopen('php://memory', 'r'), 'resource(%d) of type (stream)'),
array('1', "'1'"),
array(array(array(1,2,3), array(3,4,5)),
<<<EOF
Array &0 (
0 => Array &1 (
0 => 1
1 => 2
2 => 3
)
1 => Array &2 (
0 => 3
1 => 4
2 => 5
)
)
EOF
),
// \n\r and \r is converted to \n
array("this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext",
<<<EOF
'this
is
a
very
very
very
very
very
very
long
text'
EOF
),
array(new stdClass, 'stdClass Object &%x ()'),
array($obj,
<<<EOF
stdClass Object &%x (
'null' => null
'boolean' => true
'integer' => 1
'double' => 1.2
'string' => '1'
'text' => 'this
is
a
very
very
very
very
very
very
long
text'
'object' => stdClass Object &%x (
'foo' => 'bar'
)
'objectagain' => stdClass Object &%x
'array' => Array &%d (
'foo' => 'bar'
)
'self' => stdClass Object &%x
)
EOF
),
array(array(), 'Array &%d ()'),
array($array,
<<<EOF
Array &%d (
0 => 0
'null' => null
'boolean' => true
'integer' => 1
'double' => 1.2
'string' => '1'
'text' => 'this
is
a
very
very
very
very
very
very
long
text'
'object' => stdClass Object &%x (
'foo' => 'bar'
)
'objectagain' => stdClass Object &%x
'array' => Array &%d (
'foo' => 'bar'
)
'self' => Array &%d (
0 => 0
'null' => null
'boolean' => true
'integer' => 1
'double' => 1.2
'string' => '1'
'text' => 'this
is
a
very
very
very
very
very
very
long
text'
'object' => stdClass Object &%x
'objectagain' => stdClass Object &%x
'array' => Array &%d (
'foo' => 'bar'
)
'self' => Array &%d
)
)
EOF
),
array(
chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5),
'Binary String: 0x000102030405'
),
array(
implode('', array_map('chr', range(0x0e, 0x1f))),
'Binary String: 0x0e0f101112131415161718191a1b1c1d1e1f'
),
array(
chr(0x00) . chr(0x09),
'Binary String: 0x0009'
),
array(
'',
"''"
),
);
}
/**
* @dataProvider exportProvider
*/
public function testExport($value, $expected)
{
$this->assertStringMatchesFormat($expected, self::trimnl(Exporter::export($value)));
}
public function shortenedExportProvider()
{
$obj = new stdClass;
$obj->foo = 'bar';
$array = array(
'foo' => 'bar',
);
return array(
array(NULL, 'null'),
array(TRUE, 'true'),
array(1, '1'),
array(1.0, '1.0'),
array(1.2, '1.2'),
array('1', "'1'"),
// \n\r and \r is converted to \n
array("this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext", "'this\\nis\\na\\nvery\\nvery\\nvery\\nvery...g\\ntext'"),
array(new stdClass, 'stdClass Object ()'),
array($obj, 'stdClass Object (...)'),
array(array(), 'Array ()'),
array($array, 'Array (...)'),
);
}
/**
* @dataProvider shortenedExportProvider
*/
public function testShortenedExport($value, $expected)
{
$this->assertSame($expected, self::trimnl(Exporter::shortenedExport($value)));
}
public function provideNonBinaryMultibyteStrings()
{
return array(
array(implode('', array_map('chr', range(0x09, 0x0d))), 5),
array(implode('', array_map('chr', range(0x20, 0x7f))), 96),
array(implode('', array_map('chr', range(0x80, 0xff))), 128),
);
}
/**
* @dataProvider provideNonBinaryMultibyteStrings
*/
public function testNonBinaryStringExport($value, $expectedLength)
{
$this->assertRegExp("~'.{{$expectedLength}}'\$~s", Exporter::export($value));
}
}