Project

General

Profile

Feature #23956 » 16267.diff

Administrator Admin, 2010-11-05 16:51

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
......
t3lib_div::dirname($input)
);
}
/////////////////////////////////////////////////////////////////////////////////////
// Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
/////////////////////////////////////////////////////////////////////////////////////
/**
* @test
*
* @expectedException InvalidArgumentException
*/
public function makeInstanceWithEmptyClassNameThrowsException() {
t3lib_div::makeInstance('');
}
/**
* @test
*/
public function makeInstanceCanReturnInstanceOfNonSingletonClass() {
$className = get_class($this->getMock('foo'));
$this->assertTrue(
t3lib_div::makeInstance($className) instanceof $className
);
}
/**
* @test
*/
public function makeInstancePassesParametersToConstructor() {
$className = 'testingClass' . uniqid();
if (!class_exists($className, FALSE)) {
eval(
'class ' . $className . ' {' .
' public $constructorParameter;' .
' public function __construct($parameter) {' .
' $this->constructorParameter = $parameter;' .
' }' .
'}'
);
}
$instance = t3lib_div::makeInstance($className, 42);
$this->assertEquals(
42,
$instance->constructorParameter
);
}
/**
* @test
*/
public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
$className = get_class($this->getMock('foo'));
$this->assertNotSame(
t3lib_div::makeInstance($className),
t3lib_div::makeInstance($className)
);
}
/**
* @test
*/
public function makeInstanceCanReturnInstanceOfSingletonClass() {
$singletonClassName = get_class($this->getMock('t3lib_Singleton'));
$this->assertTrue(
t3lib_div::makeInstance($singletonClassName) instanceof $singletonClassName
);
}
/**
* @test
*/
public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
$className = get_class($this->getMock('t3lib_Singleton'));
$this->assertSame(
t3lib_div::makeInstance($className),
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)
Backend
=======
* The frameset was removed. This makes the Backend a lot faster.
* The frameset was removed. This makes the Backend a lot faster.
Now the navigation tree also can be resized. The new backend works
using the ExtJS viewport, providing an easy and unified interface
to manipulate the content of the different panels.
......
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
==========
(1-1/2)