Project

General

Profile

Feature #23956 » 16267-v2.diff

Administrator Admin, 2010-11-26 09:48

View differences:

tests/t3lib/t3lib_divTest.php (working copy)
* @subpackage t3lib
*/
class t3lib_divTest extends tx_phpunit_testcase {
/**
* Enable backup of global and system variables
*
......
*/
protected $backupGlobalsBlacklist = array('TYPO3_DB');
public function tearDown() {
t3lib_div::purgeInstances();
}
///////////////////////////////
// Tests concerning validIP
......
}
//////////////////////////////////
// Tests concerning makeInstance
//////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
// Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
/////////////////////////////////////////////////////////////////////////////////////
/**
* @test
*
* @expectedException InvalidArgumentException
*/
public function makeInstanceWithEmptyClassNameThrowsException() {
t3lib_div::makeInstance('');
}
/**
* @test
*/
public function makeInstanceReturnsClassInstance() {
$className = get_class($this->getMock('foo'));
......
t3lib_div::makeInstance($className)
);
}
/**
* @test
*/
public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
$className = get_class($this->getMock('t3lib_Singleton'));
$instance = t3lib_div::makeInstance($className);
t3lib_div::purgeInstances();
$this->assertNotSame(
$instance,
t3lib_div::makeInstance($className)
);
}
/**
* @test
*
* @expectedException InvalidArgumentException
*/
public function setSingletonInstanceForEmptyClassNameThrowsException() {
$instance = $this->getMock('t3lib_Singleton');
t3lib_div::setSingletonInstance('', $instance);
}
/**
* @test
*
* @expectedException InvalidArgumentException
*/
public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
$instance = $this->getMock('t3lib_Singleton', array('foo'));
$singletonClassName = get_class($this->getMock('t3lib_Singleton'));
t3lib_div::setSingletonInstance($singletonClassName, $instance);
}
/**
* @test
*/
public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
$instance = $this->getMock('t3lib_Singleton');
$singletonClassName = get_class($instance);
t3lib_div::setSingletonInstance($singletonClassName, $instance);
$this->assertSame(
$instance,
t3lib_div::makeInstance($singletonClassName)
);
}
/**
* @test
*/
public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
$instance1 = $this->getMock('t3lib_Singleton');
$singletonClassName = get_class($instance1);
$instance2 = new $singletonClassName();
t3lib_div::setSingletonInstance($singletonClassName, $instance1);
t3lib_div::setSingletonInstance($singletonClassName, $instance2);
$this->assertSame(
$instance2,
t3lib_div::makeInstance($singletonClassName)
);
}
/**
* @test
*
* @expectedException InvalidArgumentException
*/
public function addInstanceForEmptyClassNameThrowsException() {
$instance = $this->getMock('foo');
t3lib_div::addInstance('', $instance);
}
/**
* @test
*
* @expectedException InvalidArgumentException
*/
public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
$instance = $this->getMock('foo', array('bar'));
$singletonClassName = get_class($this->getMock('foo'));
t3lib_div::addInstance($singletonClassName, $instance);
}
/**
* @test
*
* @expectedException InvalidArgumentException
*/
public function addInstanceWithSingletonInstanceThrowsException() {
$instance = $this->getMock('t3lib_Singleton');
t3lib_div::addInstance(get_class($instance), $instance);
}
/**
* @test
*/
public function addInstanceMakesMakeInstanceReturnThatInstance() {
$instance = $this->getMock('foo');
$className = get_class($instance);
t3lib_div::addInstance($className, $instance);
$this->assertSame(
$instance,
t3lib_div::makeInstance($className)
);
}
/**
* @test
*/
public function makeInstanceCalledTwoTimesAfterAddInstanceReturnTwoDifferentInstances() {
$instance = $this->getMock('foo');
$className = get_class($instance);
t3lib_div::addInstance($className, $instance);
$this->assertNotSame(
t3lib_div::makeInstance($className),
t3lib_div::makeInstance($className)
);
}
/**
* @test
*/
public function addInstanceCalledTwoTimesMakesMakeInstanceReturnBothInstancesInAddingOrder() {
$instance1 = $this->getMock('foo');
$className = get_class($instance1);
t3lib_div::addInstance($className, $instance1);
$instance2 = new $className();
t3lib_div::addInstance($className, $instance2);
$this->assertSame(
$instance1,
t3lib_div::makeInstance($className),
'The first returned instance does not match the first added instance.'
);
$this->assertSame(
$instance2,
t3lib_div::makeInstance($className),
'The second returned instance does not match the second added instance.'
);
}
/**
* @test
*/
public function purgeInstancesDropsAddedInstance() {
$instance = $this->getMock('foo');
$className = get_class($instance);
t3lib_div::addInstance($className, $instance);
t3lib_div::purgeInstances();
$this->assertNotSame(
$instance,
t3lib_div::makeInstance($className)
);
}
}
?>
t3lib/class.t3lib_div.php (working copy)
* @subpackage t3lib
*/
final class t3lib_div {
// Severity constants used by t3lib_div::sysLog()
const SYSLOG_SEVERITY_INFO = 0;
const SYSLOG_SEVERITY_NOTICE = 1;
......
const SYSLOG_SEVERITY_ERROR = 3;
const SYSLOG_SEVERITY_FATAL = 4;
/**
* singleton instances returned by makeInstance, using the class names as
* array keys
*
* @var array<t3lib_Singleton>
*/
static protected $singletonInstances = array();
/**
* instances returned by makeInstance, using the class names as array keys
*
* @var array<array><object>
*/
static protected $nonSingletonInstances = array();
/*************************
*
......
* You can also pass arguments for a constructor:
* t3lib_div::makeInstance('myClass', $arg1, $arg2, ..., $argN)
*
* @param string Class name to instantiate
* @return object A reference to the object
* @param string $className
* name of the class to instantiate, must not be empty
*
* @return object the created instance
*/
public static function makeInstance($className) {
// holds references of singletons
static $instances = array();
if ($className === '') {
throw new InvalidArgumentException('$className must not be empty.', 1288965219);
}
// Get final classname
$className = self::getClassName($className);
$finalClassName = self::getClassName($className);
if (isset($instances[$className])) {
// it's a singleton, get the existing instance
$instance = $instances[$className];
} else {
if (func_num_args() > 1) {
// getting the constructor arguments by removing this
// method's first argument (the class name)
$constructorArguments = func_get_args();
array_shift($constructorArguments);
if (isset(self::$singletonInstances[$finalClassName])) {
return self::$singletonInstances[$finalClassName];
}
$reflectedClass = new ReflectionClass($className);
$instance = $reflectedClass->newInstanceArgs($constructorArguments);
} else {
$instance = new $className;
}
if (isset(self::$nonSingletonInstances[$finalClassName])
&& !empty(self::$nonSingletonInstances[$finalClassName])
) {
return array_shift(self::$nonSingletonInstances[$finalClassName]);
}
if ($instance instanceof t3lib_Singleton) {
// it's a singleton, save the instance for later reuse
$instances[$className] = $instance;
}
if (func_num_args() > 1) {
$constructorArguments = func_get_args();
array_shift($constructorArguments);
$reflectedClass = new ReflectionClass($finalClassName);
$instance = $reflectedClass->newInstanceArgs($constructorArguments);
} else {
$instance = new $finalClassName;
}
if ($instance instanceof t3lib_Singleton) {
self::$singletonInstances[$finalClassName] = $instance;
}
return $instance;
......
}
/**
* Sets the instance of a singleton class to be returned by makeInstance.
*
* If this function is called multiple times for the same $className,
* makeInstance will return the last set instance.
*
* This function is intendend help with unit testing.
*
* @param string $className
* the name of the class to set, must not be empty
* @param t3lib_Singleton $instance
* the instance to set, must be an instance of $className
*
* @return void
*
* @see makeInstance
*/
public function setSingletonInstance($className, t3lib_Singleton $instance) {
self::checkInstanceClassName($className, $instance);
self::$singletonInstances[$className] = $instance;
}
/**
* Sets the instance of a non-singleton class to be returned by makeInstance.
*
* If this function is called multiple times for the same $className,
* makeInstance will return the instances in the order in which they have
* been added.
*
* This function is intendend help with unit testing.
*
* @param string $className
* the name of the class to set, must not be empty
* @param object $instance
* the instance to set, must be an instance of $className
*
* @return void
*
* @see makeInstance
*/
public function addInstance($className, $instance) {
self::checkInstanceClassName($className, $instance);
if ($instance instanceof t3lib_Singleton) {
throw new InvalidArgumentException(
'$instance must not be an instance of t3lib_Singleton. ' .
'For setting singletons, please use setSingletonInstance.',
1288969325
);
}
if (!isset(self::$nonSingletonInstances[$className])) {
self::$nonSingletonInstances[$className] = array();
}
self::$nonSingletonInstances[$className][] = $instance;
}
/**
* Checks that $className is non-empty and that $instance is an instance of
* $className.
*
* @param string $className a class name
* @param object $instance an object
*
* @throws InvalidArgumentException
* if $className is empty or if $instance is no instance of $className
*/
static protected function checkInstanceClassName($className, $instance) {
if ($className === '') {
throw new InvalidArgumentException('$className must not be empty.', 1288967479);
}
if (!($instance instanceof $className)) {
throw new InvalidArgumentException(
'$instance must be an instance of ' . $className . ', but actually is an instance of ' . get_class($instance) . '.',
1288967686
);
}
}
/**
* Purges all instances returned by makeInstance.
*
* This function is most useful when called from tearDown in a testcase
* to drop any instances that have been created by the tests.
*
* @return void
*
* @see makeInstance
*/
static public function purgeInstances() {
self::$singletonInstances = array();
self::$nonSingletonInstances = array();
}
/**
* Find the best service and check if it works.
* Returns object of the service class.
*
......
echo $obContent;
}
}
?>
NEWS.txt (working copy)
having no console like the IE
* ExtDirect is available in the frontend now (#15754):
http://wiki.typo3.org/ExtDirect
* t3lib_div now provides two functions setSingletonInstance and addInstance
that will set the objects to be returned by makeInstance. (#16267)
This will allow unit tests to inject mocks into makeInstance.
In addition, there now is a function purgeInstances that makes
makeInstance return fresh instances (singleton as well as non-singleton).
TypoScript
==========
(2-2/2)