.gitignore 0000644 00000000066 14055212630 0006534 0 ustar 00 phpunit.xml
composer.lock
build
vendor
coverage.clover .scrutinizer.yml 0000644 00000002221 14055212630 0007721 0 ustar 00 before_commands:
- "composer install --prefer-source"
tools:
external_code_coverage:
timeout: 600
php_code_coverage:
enabled: true
test_command: ./vendor/bin/phpunit
php_code_sniffer:
enabled: true
config:
standard: PSR2
filter:
paths: ["src/*", "tests/*"]
php_cpd:
enabled: true
excluded_dirs: ["build/*", "tests", "vendor"]
php_cs_fixer:
enabled: true
config:
level: all
filter:
paths: ["src/*", "tests/*"]
php_loc:
enabled: true
excluded_dirs: ["build", "tests", "vendor"]
php_mess_detector:
enabled: true
config:
ruleset: phpmd.xml.dist
design_rules: { eval_expression: false }
filter:
paths: ["src/*"]
php_pdepend:
enabled: true
excluded_dirs: ["build", "tests", "vendor"]
php_analyzer:
enabled: true
filter:
paths: ["src/*", "tests/*"]
php_hhvm:
enabled: true
filter:
paths: ["src/*", "tests/*"]
sensiolabs_security_checker: true
.travis.install.sh 0000755 00000001030 14055212630 0010126 0 ustar 00 set -x
if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ] || [ "$TRAVIS_PHP_VERSION" = 'hhvm-nightly' ] ; then
curl -sS https://getcomposer.org/installer > composer-installer.php
hhvm composer-installer.php
hhvm -v ResourceLimit.SocketDefaultTimeout=30 -v Http.SlowQueryThreshold=30000 composer.phar update --prefer-source
elif [ "$TRAVIS_PHP_VERSION" = '5.3.3' ] ; then
composer self-update
composer update --prefer-source --no-dev
composer dump-autoload
else
composer self-update
composer update --prefer-source
fi
.travis.yml 0000644 00000001655 14055212630 0006662 0 ustar 00 language: php
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
- hhvm-nightly
before_script:
- ./.travis.install.sh
script:
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.3.3' ]; then phpunit; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.3.3' ]; then ./vendor/bin/phpunit; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.3.3' ]; then ./vendor/bin/phpcs --standard=PSR2 ./src/ ./tests/; fi"
- sh -c "if [[ '$TRAVIS_PHP_VERSION' != '5.3.3' && '$TRAVIS_PHP_VERSION' != '5.4.29' && '$TRAVIS_PHP_VERSION' != '5.5.13' ]]; then php -n ./vendor/bin/athletic -p ./tests/InstantiatorPerformance/ -f GroupedFormatter; fi"
after_script:
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.3.3' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi"
matrix:
allow_failures:
- php: 5.6 # Depends on https://github.com/php/php-src/pull/733
- php: hhvm-nightly
CONTRIBUTING.md 0000644 00000002073 14055212630 0006775 0 ustar 00 # Contributing
* Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
* The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
* Any contribution must provide tests for additional introduced conditions
* Any un-confirmed issue needs a failing test case before being accepted
* Pull requests must be sent from a new hotfix/feature branch, not from `master`.
## Installation
To install the project and run the tests, you need to clone it first:
```sh
$ git clone git://github.com/Ocramius/Instantiator.git
```
You will then need to run a composer installation:
```sh
$ cd Instantiator
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar update
```
## Testing
The PHPUnit version to be used is the one installed as a dev- dependency via composer:
```sh
$ ./vendor/bin/phpunit
```
Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement
won't be merged.
LICENSE 0000644 00000002041 14055212630 0005544 0 ustar 00 Copyright (c) 2014 Marco Pivetta
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
README.md 0000644 00000005006 14055212630 0006022 0 ustar 00 # Instantiator
This library provides a way of avoiding usage of constructors when instantiating PHP classes.
## Deprecated in favour of [doctrine/instantiator](https://github.com/doctrine/instantiator)
This library has been donated to the [doctrine organization](http://doctrine-project.org/) and
has been renamed to [doctrine/instantiator](https://github.com/doctrine/instantiator). This
repository/package is deprecated.
The library will still be maintained, but there won't be any new feature additions,
and BC breaks will be refused, as no more future major versions are planned.
Bugs and security issues will still be fixed, and minor-, as well as patch- releases
will be tagged if needed.
It is strongly suggested to use [doctrine/instantiator](https://github.com/doctrine/instantiator)
instead.
## Status
[![Build Status](https://travis-ci.org/Ocramius/Instantiator.svg?branch=master)](https://travis-ci.org/Ocramius/Instantiator)
[![Code Coverage](https://scrutinizer-ci.com/g/Ocramius/Instantiator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Ocramius/Instantiator/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Ocramius/Instantiator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Ocramius/Instantiator/?branch=master)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/7a2c1cd1-5197-4822-8a4c-5ddaca48c769/mini.png)](https://insight.sensiolabs.com/projects/7a2c1cd1-5197-4822-8a4c-5ddaca48c769)
[![Dependency Status](https://www.versioneye.com/package/php--ocramius--instantiator/badge.svg)](https://www.versioneye.com/package/php--ocramius--instantiator)
[![HHVM Status](http://hhvm.h4cc.de/badge/ocramius/instantiator.png)](http://hhvm.h4cc.de/package/ocramius/instantiator)
[![Latest Stable Version](https://poser.pugx.org/ocramius/instantiator/v/stable.png)](https://packagist.org/packages/ocramius/instantiator)
[![Latest Unstable Version](https://poser.pugx.org/ocramius/instantiator/v/unstable.png)](https://packagist.org/packages/ocramius/instantiator)
## Installation
The suggested installation method is via [composer](https://getcomposer.org/):
```sh
php composer.phar require ocramius/instantiator:1.1.*
```
## Usage
The instantiator is able to create new instances of any class without using the constructor of the class
itself:
```php
$instantiator = new \Instantiator\Instantiator();
$instance = $instantiator->instantiate('My\\ClassName\\Here');
```
## Contributing
Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out!
composer.json 0000644 00000002442 14055212630 0007266 0 ustar 00 {
"name": "ocramius/instantiator",
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"type": "library",
"license": "MIT",
"homepage": "https://github.com/Ocramius/Instantiator",
"keywords": [
"instantiate",
"constructor"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "http://ocramius.github.com/"
}
],
"require": {
"php": "~5.3",
"ocramius/lazy-map": "1.0.*"
},
"require-dev": {
"ext-phar": "*",
"ext-pdo": "*",
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "2.0.*@ALPHA",
"athletic/athletic": "~0.1.8"
},
"autoload": {
"psr-0": {
"Instantiator\\": "src"
}
},
"autoload-dev": {
"psr-0": {
"InstantiatorPerformance\\": "tests",
"InstantiatorTest\\": "tests",
"InstantiatorTestAsset\\": "tests"
}
},
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
}
}
phpmd.xml.dist 0000644 00000002075 14055212630 0007342 0 ustar 00
phpunit.xml.dist 0000644 00000001303 14055212630 0007712 0 ustar 00
./tests/InstantiatorTest
./src
src/Instantiator/Exception/ExceptionInterface.php 0000644 00000002134 14055212630 0016236 0 ustar 00
*/
interface ExceptionInterface
{
}
src/Instantiator/Exception/InvalidArgumentException.php 0000644 00000004253 14055212630 0017433 0 ustar 00
*/
class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
{
/**
* @param string $className
*
* @return self
*/
public static function fromNonExistingClass($className)
{
if (interface_exists($className)) {
return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
}
if (PHP_VERSION_ID >= 50400 && trait_exists($className)) {
return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
}
return new self(sprintf('The provided class "%s" does not exist', $className));
}
/**
* @param ReflectionClass $reflectionClass
*
* @return self
*/
public static function fromAbstractClass(ReflectionClass $reflectionClass)
{
return new self(sprintf(
'The provided class "%s" is abstract, and can not be instantiated',
$reflectionClass->getName()
));
}
}
src/Instantiator/Exception/UnexpectedValueException.php 0000644 00000005205 14055212630 0017441 0 ustar 00
*/
class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
{
/**
* @param ReflectionClass $reflectionClass
* @param Exception $exception
*
* @return self
*/
public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception)
{
return new self(
sprintf(
'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
$reflectionClass->getName()
),
0,
$exception
);
}
/**
* @param ReflectionClass $reflectionClass
* @param string $errorString
* @param int $errorCode
* @param string $errorFile
* @param int $errorLine
*
* @return UnexpectedValueException
*/
public static function fromUncleanUnSerialization(
ReflectionClass $reflectionClass,
$errorString,
$errorCode,
$errorFile,
$errorLine
) {
return new self(
sprintf(
'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
. 'in file "%s" at line "%d"',
$reflectionClass->getName(),
$errorFile,
$errorLine
),
0,
new Exception($errorString, $errorCode)
);
}
}
src/Instantiator/Instantiator.php 0000644 00000020356 14055212630 0013206 0 ustar 00
*/
final class Instantiator implements InstantiatorInterface
{
/**
* Markers used internally by PHP to define whether {@see \unserialize} should invoke
* the method {@see \Serializable::unserialize()} when dealing with classes implementing
* the {@see \Serializable} interface.
*/
const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
/**
* @var CallbackLazyMap of {@see \Closure} instances
*/
private static $cachedInstantiators;
/**
* @var CallbackLazyMap of objects that can directly be cloned
*/
private static $cachedCloneables;
/**
* Constructor.
*/
public function __construct()
{
// initialize static cached state, if not done before
self::$cachedInstantiators = $this->getInstantiatorsMap();
self::$cachedCloneables = $this->getCloneablesMap();
}
/**
* {@inheritDoc}
*/
public function instantiate($className)
{
if ($cloneable = self::$cachedCloneables->$className) {
return clone $cloneable;
}
$factory = self::$cachedInstantiators->$className;
/* @var $factory Closure */
return $factory();
}
/**
* @internal
* @private
*
* Builds a {@see \Closure} capable of instantiating the given $className without
* invoking its constructor.
* This method is only exposed as public because of PHP 5.3 compatibility. Do not
* use this method in your own code
*
* @param string $className
*
* @return Closure
*/
public function buildFactory($className)
{
$reflectionClass = $this->getReflectionClass($className);
if ($this->isInstantiableViaReflection($reflectionClass)) {
return function () use ($reflectionClass) {
return $reflectionClass->newInstanceWithoutConstructor();
};
}
$serializedString = sprintf(
'%s:%d:"%s":0:{}',
$this->getSerializationFormat($reflectionClass),
strlen($className),
$className
);
$this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
return function () use ($serializedString) {
return unserialize($serializedString);
};
}
/**
* @param string $className
*
* @return ReflectionClass
*
* @throws InvalidArgumentException
*/
private function getReflectionClass($className)
{
if (! class_exists($className)) {
throw InvalidArgumentException::fromNonExistingClass($className);
}
$reflection = new ReflectionClass($className);
if ($reflection->isAbstract()) {
throw InvalidArgumentException::fromAbstractClass($reflection);
}
return $reflection;
}
/**
* @param ReflectionClass $reflectionClass
* @param string $serializedString
*
* @throws UnexpectedValueException
*
* @return void
*/
private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString)
{
set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) {
$error = UnexpectedValueException::fromUncleanUnSerialization(
$reflectionClass,
$message,
$code,
$file,
$line
);
});
try {
unserialize($serializedString);
} catch (Exception $exception) {
restore_error_handler();
throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
}
restore_error_handler();
if ($error) {
throw $error;
}
}
/**
* @param ReflectionClass $reflectionClass
*
* @return bool
*/
private function isInstantiableViaReflection(ReflectionClass $reflectionClass)
{
if (\PHP_VERSION_ID >= 50600) {
return ! ($reflectionClass->isInternal() && $reflectionClass->isFinal());
}
return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass);
}
/**
* Verifies whether the given class is to be considered internal
*
* @param ReflectionClass $reflectionClass
*
* @return bool
*/
private function hasInternalAncestors(ReflectionClass $reflectionClass)
{
do {
if ($reflectionClass->isInternal()) {
return true;
}
} while ($reflectionClass = $reflectionClass->getParentClass());
return false;
}
/**
* Verifies if the given PHP version implements the `Serializable` interface serialization
* with an incompatible serialization format. If that's the case, use serialization marker
* "C" instead of "O".
*
* @link http://news.php.net/php.internals/74654
*
* @param ReflectionClass $reflectionClass
*
* @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER
* or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER
*/
private function getSerializationFormat(ReflectionClass $reflectionClass)
{
if ($this->isPhpVersionWithBrokenSerializationFormat()
&& $reflectionClass->implementsInterface('Serializable')
) {
return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER;
}
return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER;
}
/**
* Checks whether the current PHP runtime uses an incompatible serialization format
*
* @return bool
*/
private function isPhpVersionWithBrokenSerializationFormat()
{
return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513;
}
/**
* Builds or fetches the instantiators map
*
* @return CallbackLazyMap
*/
private function getInstantiatorsMap()
{
$that = $this; // PHP 5.3 compatibility
return self::$cachedInstantiators = self::$cachedInstantiators
?: new CallbackLazyMap(function ($className) use ($that) {
return $that->buildFactory($className);
});
}
/**
* Builds or fetches the cloneables map
*
* @return CallbackLazyMap
*/
private function getCloneablesMap()
{
$cachedInstantiators = $this->getInstantiatorsMap();
return self::$cachedCloneables = self::$cachedCloneables
?: new CallbackLazyMap(function ($className) use ($cachedInstantiators) {
/* @var $factory Closure */
$factory = $cachedInstantiators->$className;
$instance = $factory();
$reflection = new ReflectionClass($instance);
// not cloneable if it implements `__clone`, as we want to avoid calling it
if ($reflection->hasMethod('__clone')) {
return null;
}
return $instance;
});
}
}
src/Instantiator/InstantiatorInterface.php 0000644 00000002454 14055212630 0015026 0 ustar 00
*/
interface InstantiatorInterface
{
/**
* @param string $className
*
* @return object
*
* @throws \Instantiator\Exception\ExceptionInterface
*/
public function instantiate($className);
}
tests/InstantiatorPerformance/InstantiatorPerformanceEvent.php 0000644 00000005506 14055212630 0021127 0 ustar 00
*/
class InstantiatorPerformanceEvent extends AthleticEvent
{
/**
* @var \Instantiator\Instantiator
*/
private $instantiator;
/**
* {@inheritDoc}
*/
protected function setUp()
{
$this->instantiator = new Instantiator();
$this->instantiator->instantiate(__CLASS__);
$this->instantiator->instantiate('ArrayObject');
$this->instantiator->instantiate('InstantiatorTestAsset\\SimpleSerializableAsset');
$this->instantiator->instantiate('InstantiatorTestAsset\\SerializableArrayObjectAsset');
$this->instantiator->instantiate('InstantiatorTestAsset\\UnCloneableAsset');
}
/**
* @iterations 20000
* @baseline
* @group instantiation
*/
public function testInstantiateSelf()
{
$this->instantiator->instantiate(__CLASS__);
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateInternalClass()
{
$this->instantiator->instantiate('ArrayObject');
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateSimpleSerializableAssetClass()
{
$this->instantiator->instantiate('InstantiatorTestAsset\\SimpleSerializableAsset');
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateSerializableArrayObjectAsset()
{
$this->instantiator->instantiate('InstantiatorTestAsset\\SerializableArrayObjectAsset');
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateUnCloneableAsset()
{
$this->instantiator->instantiate('InstantiatorTestAsset\\UnCloneableAsset');
}
}
tests/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php 0000644 00000006011 14055212630 0021500 0 ustar 00
*
* @covers \Instantiator\Exception\InvalidArgumentException
*/
class InvalidArgumentExceptionTest extends PHPUnit_Framework_TestCase
{
public function testFromNonExistingTypeWithNonExistingClass()
{
$className = __CLASS__ . uniqid();
$exception = InvalidArgumentException::fromNonExistingClass($className);
$this->assertInstanceOf('Instantiator\\Exception\\InvalidArgumentException', $exception);
$this->assertSame('The provided class "' . $className . '" does not exist', $exception->getMessage());
}
public function testFromNonExistingTypeWithTrait()
{
if (PHP_VERSION_ID < 50400) {
$this->markTestSkipped('Need at least PHP 5.4.0, as this test requires traits support to run');
}
$exception = InvalidArgumentException::fromNonExistingClass('InstantiatorTestAsset\\SimpleTraitAsset');
$this->assertSame(
'The provided type "InstantiatorTestAsset\\SimpleTraitAsset" is a trait, and can not be instantiated',
$exception->getMessage()
);
}
public function testFromNonExistingTypeWithInterface()
{
$exception = InvalidArgumentException::fromNonExistingClass('Instantiator\\InstantiatorInterface');
$this->assertSame(
'The provided type "Instantiator\\InstantiatorInterface" is an interface, and can not be instantiated',
$exception->getMessage()
);
}
public function testFromAbstractClass()
{
$reflection = new ReflectionClass('InstantiatorTestAsset\\AbstractClassAsset');
$exception = InvalidArgumentException::fromAbstractClass($reflection);
$this->assertSame(
'The provided class "InstantiatorTestAsset\\AbstractClassAsset" is abstract, and can not be instantiated',
$exception->getMessage()
);
}
}
tests/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php 0000644 00000005457 14055212630 0021525 0 ustar 00
*
* @covers \Instantiator\Exception\UnexpectedValueException
*/
class UnexpectedValueExceptionTest extends PHPUnit_Framework_TestCase
{
public function testFromSerializationTriggeredException()
{
$reflectionClass = new ReflectionClass($this);
$previous = new Exception();
$exception = UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $previous);
$this->assertInstanceOf('Instantiator\\Exception\\UnexpectedValueException', $exception);
$this->assertSame($previous, $exception->getPrevious());
$this->assertSame(
'An exception was raised while trying to instantiate an instance of "'
. __CLASS__ . '" via un-serialization',
$exception->getMessage()
);
}
public function testFromUncleanUnSerialization()
{
$reflection = new ReflectionClass('InstantiatorTestAsset\\AbstractClassAsset');
$exception = UnexpectedValueException::fromUncleanUnSerialization($reflection, 'foo', 123, 'bar', 456);
$this->assertInstanceOf('Instantiator\\Exception\\UnexpectedValueException', $exception);
$this->assertSame(
'Could not produce an instance of "InstantiatorTestAsset\AbstractClassAsset" via un-serialization, '
. 'since an error was triggered in file "bar" at line "456"',
$exception->getMessage()
);
$previous = $exception->getPrevious();
$this->assertInstanceOf('Exception', $previous);
$this->assertSame('foo', $previous->getMessage());
$this->assertSame(123, $previous->getCode());
}
}
tests/InstantiatorTest/InstantiatorTest.php 0000644 00000015701 14055212630 0015257 0 ustar 00
*
* @covers \Instantiator\Instantiator
*/
class InstantiatorTest extends PHPUnit_Framework_TestCase
{
/**
* @var Instantiator
*/
private $instantiator;
/**
* {@inheritDoc}
*/
protected function setUp()
{
$this->instantiator = new Instantiator();
}
/**
* @param string $className
*
* @dataProvider getInstantiableClasses
*/
public function testCanInstantiate($className)
{
$this->assertInstanceOf($className, $this->instantiator->instantiate($className));
}
/**
* @param string $className
*
* @dataProvider getInstantiableClasses
*/
public function testInstantiatesSeparateInstances($className)
{
$instance1 = $this->instantiator->instantiate($className);
$instance2 = $this->instantiator->instantiate($className);
$this->assertEquals($instance1, $instance2);
$this->assertNotSame($instance1, $instance2);
}
public function testExceptionOnUnSerializationException()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped(
'As of facebook/hhvm#3432, HHVM has no PDORow, and therefore '
. ' no internal final classes that cannot be instantiated'
);
}
$className = 'InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset';
if (\PHP_VERSION_ID >= 50600) {
$className = 'PDORow';
}
if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) {
$className = 'InstantiatorTestAsset\\SerializableArrayObjectAsset';
}
$this->setExpectedException('Instantiator\\Exception\\UnexpectedValueException');
$this->instantiator->instantiate($className);
}
public function testNoticeOnUnSerializationException()
{
if (\PHP_VERSION_ID >= 50600) {
$this->markTestSkipped(
'PHP 5.6 supports `ReflectionClass#newInstanceWithoutConstructor()` for some internal classes'
);
}
ob_start();
try {
$this->instantiator->instantiate('InstantiatorTestAsset\\WakeUpNoticesAsset');
ob_end_clean();
$this->fail('No exception was raised');
} catch (UnexpectedValueException $exception) {
$wakeUpNoticesReflection = new ReflectionClass('InstantiatorTestAsset\WakeUpNoticesAsset');
$previous = $exception->getPrevious();
$this->assertInstanceOf('Exception', $previous);
// in PHP 5.4.29 and PHP 5.5.13, this case is not a notice, but an exception being thrown
if (! (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513)) {
$this->assertSame(
'Could not produce an instance of "InstantiatorTestAsset\WakeUpNoticesAsset" via un-serialization, '
. 'since an error was triggered in file "'
. $wakeUpNoticesReflection->getFileName() . '" at line "35"',
$exception->getMessage()
);
$this->assertSame('Something went bananas while un-serializing this instance', $previous->getMessage());
$this->assertSame(\E_USER_NOTICE, $previous->getCode());
}
}
ob_end_clean();
}
/**
* @param string $invalidClassName
*
* @dataProvider getInvalidClassNames
*/
public function testInstantiationFromNonExistingClass($invalidClassName)
{
$this->setExpectedException('Instantiator\\Exception\\InvalidArgumentException');
$this->instantiator->instantiate($invalidClassName);
}
public function testInstancesAreNotCloned()
{
$className = 'TemporaryClass' . uniqid();
eval('namespace ' . __NAMESPACE__ . '; class ' . $className . '{}');
$instance = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className);
$instance->foo = 'bar';
$instance2 = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className);
$this->assertObjectNotHasAttribute('foo', $instance2);
}
/**
* Provides a list of instantiable classes (existing)
*
* @return string[][]
*/
public function getInstantiableClasses()
{
$classes = array(
array('stdClass'),
array(__CLASS__),
array('Instantiator\\Instantiator'),
array('PharException'),
array('InstantiatorTestAsset\\SimpleSerializableAsset'),
array('InstantiatorTestAsset\\PharExceptionAsset'),
array('InstantiatorTestAsset\\UnCloneableAsset'),
);
if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) {
return $classes;
}
$classes = array_merge(
$classes,
array(
array('PharException'),
array('ArrayObject'),
array('InstantiatorTestAsset\\ArrayObjectAsset'),
array('InstantiatorTestAsset\\SerializableArrayObjectAsset'),
)
);
if (\PHP_VERSION_ID >= 50600) {
$classes[] = array('InstantiatorTestAsset\\WakeUpNoticesAsset');
$classes[] = array('InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset');
}
return $classes;
}
/**
* Provides a list of instantiable classes (existing)
*
* @return string[][]
*/
public function getInvalidClassNames()
{
$classNames = array(
array(__CLASS__ . uniqid()),
array('Instantiator\\InstantiatorInterface'),
array('InstantiatorTestAsset\\AbstractClassAsset'),
);
if (\PHP_VERSION_ID >= 50400) {
$classNames[] = array('InstantiatorTestAsset\\SimpleTraitAsset');
}
return $classNames;
}
}
tests/InstantiatorTestAsset/AbstractClassAsset.php 0000644 00000002106 14055212630 0016464 0 ustar 00
*/
abstract class AbstractClassAsset
{
}
tests/InstantiatorTestAsset/ArrayObjectAsset.php 0000644 00000002543 14055212630 0016145 0 ustar 00
*/
class ArrayObjectAsset extends ArrayObject
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
tests/InstantiatorTestAsset/PharAsset.php 0000644 00000002516 14055212630 0014632 0 ustar 00
*/
class PharAsset extends Phar
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
tests/InstantiatorTestAsset/PharExceptionAsset.php 0000644 00000002755 14055212630 0016516 0 ustar 00
*/
class PharExceptionAsset extends PharException
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
tests/InstantiatorTestAsset/SerializableArrayObjectAsset.php 0000644 00000003403 14055212630 0020470 0 ustar 00
*/
class SerializableArrayObjectAsset extends ArrayObject implements Serializable
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
/**
* {@inheritDoc}
*/
public function serialize()
{
return '';
}
/**
* {@inheritDoc}
*
* Should not be called
*
* @throws BadMethodCallException
*/
public function unserialize($serialized)
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
tests/InstantiatorTestAsset/SimpleSerializableAsset.php 0000644 00000003272 14055212630 0017520 0 ustar 00
*/
class SimpleSerializableAsset implements Serializable
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
/**
* {@inheritDoc}
*/
public function serialize()
{
return '';
}
/**
* {@inheritDoc}
*
* Should not be called
*
* @throws BadMethodCallException
*/
public function unserialize($serialized)
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
tests/InstantiatorTestAsset/SimpleTraitAsset.php 0000644 00000002074 14055212630 0016174 0 ustar 00
*/
trait SimpleTraitAsset
{
}
tests/InstantiatorTestAsset/UnCloneableAsset.php 0000644 00000003007 14055212630 0016123 0 ustar 00
*/
class UnCloneableAsset
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
/**
* Magic `__clone` - should not be invoked
*
* @throws BadMethodCallException
*/
public function __clone()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
tests/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php 0000644 00000002415 14055212630 0022235 0 ustar 00
*/
class UnserializeExceptionArrayObjectAsset extends ArrayObject
{
/**
* {@inheritDoc}
*/
public function __wakeup()
{
throw new BadMethodCallException();
}
}
tests/InstantiatorTestAsset/WakeUpNoticesAsset.php 0000644 00000002445 14055212630 0016462 0 ustar 00
*/
class WakeUpNoticesAsset extends ArrayObject
{
/**
* Wakeup method called after un-serialization
*/
public function __wakeup()
{
trigger_error('Something went bananas while un-serializing this instance');
}
}