2008-03-19 21:38:58 +01:00
|
|
|
<?php
|
2008-06-15 15:33:53 +02:00
|
|
|
/**
|
|
|
|
* @package sapphire
|
|
|
|
* @subpackage tests
|
2008-10-15 19:09:43 +02:00
|
|
|
*
|
|
|
|
* @todo tests for addStaticVars()
|
|
|
|
* @todo tests for setting statics which are not defined on the object as built-in PHP statics
|
|
|
|
* @todo tests for setting statics through decorators (#2387)
|
2008-06-15 15:33:53 +02:00
|
|
|
*/
|
2008-03-19 21:38:58 +01:00
|
|
|
class ObjectTest extends SapphireTest {
|
2008-04-26 08:32:52 +02:00
|
|
|
|
|
|
|
function testHasmethodBehaviour() {
|
|
|
|
/* SiteTree should have all of the methods that Versioned has, because Versioned is listed in SiteTree's
|
|
|
|
* extensions */
|
2008-03-19 21:38:58 +01:00
|
|
|
$st = new SiteTree();
|
|
|
|
$cc = new ContentController($st);
|
|
|
|
|
|
|
|
$this->assertTrue($st->hasMethod('publish'), "Test SiteTree has publish");
|
|
|
|
$this->assertTrue($st->hasMethod('migrateVersion'), "Test SiteTree has migrateVersion");
|
|
|
|
|
2008-04-26 08:32:52 +02:00
|
|
|
/* This relationship should be case-insensitive, too */
|
2008-03-19 21:38:58 +01:00
|
|
|
$this->assertTrue($st->hasMethod('PuBliSh'), "Test SiteTree has PuBliSh");
|
|
|
|
$this->assertTrue($st->hasMethod('MiGratEVersIOn'), "Test SiteTree has MiGratEVersIOn");
|
|
|
|
|
2008-04-26 08:32:52 +02:00
|
|
|
/* In a similar manner, all of SiteTree's methods should be available on ContentController, because $failover is set */
|
2008-03-19 21:38:58 +01:00
|
|
|
$this->assertTrue($cc->hasMethod('canView'), "Test ContentController has canView");
|
|
|
|
$this->assertTrue($cc->hasMethod('linkorcurrent'), "Test ContentController has linkorcurrent");
|
2008-04-26 08:32:52 +02:00
|
|
|
|
|
|
|
/* This 'method copying' is transitive, so all of Versioned's methods should be available on ContentControler.
|
|
|
|
* Once again, this is case-insensitive */
|
2008-03-19 21:38:58 +01:00
|
|
|
$this->assertTrue($cc->hasMethod('MiGratEVersIOn'), "Test ContentController has MiGratEVersIOn");
|
2008-03-19 21:39:07 +01:00
|
|
|
|
2008-04-26 08:32:52 +02:00
|
|
|
/* The above examples make use of SiteTree, Versioned and ContentController. Let's test defineMethods() more
|
|
|
|
* directly, with some sample objects */
|
2008-03-19 21:39:07 +01:00
|
|
|
$objs = array();
|
|
|
|
$objs[] = new ObjectTest_T2();
|
|
|
|
$objs[] = new ObjectTest_T2();
|
|
|
|
$objs[] = new ObjectTest_T2();
|
|
|
|
|
|
|
|
// All these methods should exist and return true
|
|
|
|
$trueMethods = array('testMethod','otherMethod','someMethod','t1cMethod','normalMethod');
|
|
|
|
|
|
|
|
foreach($objs as $i => $obj) {
|
|
|
|
foreach($trueMethods as $method) {
|
|
|
|
$methodU = strtoupper($method);
|
|
|
|
$methodL = strtoupper($method);
|
2009-03-14 01:16:32 +01:00
|
|
|
$this->assertTrue($obj->hasMethod($method), "Test that obj#$i has method $method ($obj->class)");
|
2008-03-19 21:39:07 +01:00
|
|
|
$this->assertTrue($obj->hasMethod($methodU), "Test that obj#$i has method $methodU");
|
|
|
|
$this->assertTrue($obj->hasMethod($methodL), "Test that obj#$i has method $methodL");
|
|
|
|
|
|
|
|
$this->assertTrue($obj->$method(), "Test that obj#$i can call method $method");
|
|
|
|
$this->assertTrue($obj->$methodU(), "Test that obj#$i can call method $methodU");
|
|
|
|
$this->assertTrue($obj->$methodL(), "Test that obj#$i can call method $methodL");
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertTrue($obj->hasMethod('Wrapping'), "Test that obj#$i has method Wrapping");
|
|
|
|
$this->assertTrue($obj->hasMethod('WRAPPING'), "Test that obj#$i has method WRAPPING");
|
|
|
|
$this->assertTrue($obj->hasMethod('wrapping'), "Test that obj#$i has method wrapping");
|
|
|
|
|
|
|
|
$this->assertEquals("Wrapping", $obj->Wrapping(), "Test that obj#$i can call method Wrapping");
|
|
|
|
$this->assertEquals("Wrapping", $obj->WRAPPING(), "Test that obj#$i can call method WRAPPIGN");
|
|
|
|
$this->assertEquals("Wrapping", $obj->wrapping(), "Test that obj#$i can call method wrapping");
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2008-10-03 17:57:32 +02:00
|
|
|
|
|
|
|
function testSingletonCreation() {
|
|
|
|
$myObject = singleton('ObjectTest_MyObject');
|
|
|
|
$this->assertEquals($myObject->class, 'ObjectTest_MyObject', 'singletons are creating a correct class instance');
|
|
|
|
$this->assertEquals(get_class($myObject), 'ObjectTest_MyObject', 'singletons are creating a correct class instance');
|
|
|
|
|
|
|
|
$mySubObject = singleton('ObjectTest_MySubObject');
|
|
|
|
$this->assertEquals($mySubObject->class, 'ObjectTest_MySubObject', 'singletons are creating a correct subclass instance');
|
|
|
|
$this->assertEquals(get_class($mySubObject), 'ObjectTest_MySubObject', 'singletons are creating a correct subclass instance');
|
|
|
|
|
|
|
|
$myFirstObject = singleton('ObjectTest_MyObject');
|
|
|
|
$mySecondObject = singleton('ObjectTest_MyObject');
|
|
|
|
$this->assertTrue($myFirstObject === $mySecondObject, 'singletons are using the same object on subsequent calls');
|
|
|
|
}
|
2008-10-15 19:05:46 +02:00
|
|
|
|
|
|
|
function testStaticGetterMethod() {
|
|
|
|
static $_SINGLETONS;
|
|
|
|
$_SINGLETONS= null;
|
|
|
|
|
|
|
|
$obj = singleton('ObjectTest_MyObject');
|
|
|
|
$this->assertEquals(
|
|
|
|
ObjectTest_MyObject::$mystaticProperty,
|
|
|
|
$obj->stat('mystaticProperty'),
|
|
|
|
'Uninherited statics through stat() on a singleton behave the same as built-in PHP statics'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testStaticInheritanceGetters() {
|
|
|
|
static $_SINGLETONS;
|
|
|
|
$_SINGLETONS = null;
|
|
|
|
|
|
|
|
$obj = singleton('ObjectTest_MyObject');
|
|
|
|
$subObj = singleton('ObjectTest_MyObject');
|
|
|
|
$this->assertEquals(
|
|
|
|
$subObj->stat('mystaticProperty'),
|
|
|
|
'MyObject',
|
|
|
|
'Statics defined on a parent class are available through stat() on a subclass'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testStaticSettingOnSingletons() {
|
|
|
|
static $_SINGLETONS;
|
|
|
|
$_SINGLETONS = null;
|
|
|
|
|
|
|
|
$singleton1 = singleton('ObjectTest_MyObject');
|
|
|
|
$singleton2 = singleton('ObjectTest_MyObject');
|
|
|
|
$singleton1->set_stat('mystaticProperty', 'changed');
|
|
|
|
$this->assertEquals(
|
|
|
|
$singleton2->stat('mystaticProperty'),
|
|
|
|
'changed',
|
|
|
|
'Statics setting is populated throughout singletons without explicitly clearing cache'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testStaticSettingOnInstances() {
|
|
|
|
static $_SINGLETONS;
|
|
|
|
$_SINGLETONS = null;
|
|
|
|
|
|
|
|
$instance1 = new ObjectTest_MyObject();
|
|
|
|
$instance2 = new ObjectTest_MyObject();
|
|
|
|
$instance1->set_stat('mystaticProperty', 'changed');
|
|
|
|
$this->assertEquals(
|
|
|
|
$instance2->stat('mystaticProperty'),
|
|
|
|
'changed',
|
|
|
|
'Statics setting through set_stat() is populated throughout instances without explicitly clearing cache'
|
|
|
|
);
|
2009-03-14 01:16:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests that {@link Object::create()} correctly passes all arguments to the new object
|
|
|
|
*/
|
|
|
|
public function testCreateWithArgs() {
|
|
|
|
$createdObj = Object::create('ObjectTest_CreateTest', 'arg1', 'arg2', array(), null, 'arg5');
|
|
|
|
$this->assertEquals($createdObj->constructArguments, array('arg1', 'arg2', array(), null, 'arg5'));
|
|
|
|
|
|
|
|
$strongObj = Object::strong_create('ObjectTest_CreateTest', 'arg1', 'arg2', array(), null, 'arg5');
|
|
|
|
$this->assertEquals($strongObj->constructArguments, array('arg1', 'arg2', array(), null, 'arg5'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests that {@link Object::useCustomClass()} correnctly replaces normal and strong objects
|
|
|
|
*/
|
|
|
|
public function testUseCustomClass() {
|
|
|
|
$obj1 = Object::create('ObjectTest_CreateTest');
|
|
|
|
$this->assertTrue($obj1->is_a('ObjectTest_CreateTest'));
|
|
|
|
|
|
|
|
Object::useCustomClass('ObjectTest_CreateTest', 'ObjectTest_CreateTest2');
|
|
|
|
$obj2 = Object::create('ObjectTest_CreateTest');
|
|
|
|
$this->assertTrue($obj2->is_a('ObjectTest_CreateTest2'));
|
|
|
|
|
|
|
|
$obj2_2 = Object::strong_create('ObjectTest_CreateTest');
|
|
|
|
$this->assertTrue($obj2_2->is_a('ObjectTest_CreateTest'));
|
|
|
|
|
|
|
|
Object::useCustomClass('ObjectTest_CreateTest', 'ObjectTest_CreateTest3', true);
|
|
|
|
$obj3 = Object::create('ObjectTest_CreateTest');
|
|
|
|
$this->assertTrue($obj3->is_a('ObjectTest_CreateTest3'));
|
|
|
|
|
|
|
|
$obj3_2 = Object::strong_create('ObjectTest_CreateTest');
|
|
|
|
$this->assertTrue($obj3_2->is_a('ObjectTest_CreateTest3'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests {@link Object::has_extension()}, {@link Object::add_extension()}
|
|
|
|
*/
|
|
|
|
public function testHasAndAddExtension() {
|
|
|
|
$this->assertTrue(Object::has_extension('ObjectTest_ExtensionTest', 'HIERACHY'));
|
|
|
|
$this->assertTrue(Object::has_extension('ObjectTest_ExtensionTest', 'translatable'));
|
|
|
|
$this->assertFalse(Object::has_extension('ObjectTest_ExtensionTest', 'Versioned'));
|
|
|
|
|
|
|
|
Object::add_extension('ObjectTest_ExtensionTest', 'VERSIONED("Stage", "Live")');
|
|
|
|
$this->assertTrue(Object::has_extension('ObjectTest_ExtensionTest', 'Versioned'));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testParentClass() {
|
|
|
|
$this->assertEquals(Object::create('ObjectTest_MyObject')->parentClass(), 'Object');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testIsA() {
|
|
|
|
$this->assertTrue(Object::create('ObjectTest_MyObject')->is_a('Object'));
|
|
|
|
$this->assertTrue(Object::create('ObjectTest_MyObject')->is_a('ObjectTest_MyObject'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests {@link Object::hasExtension() and Object::extInstance()}
|
|
|
|
*/
|
|
|
|
public function testExtInstance() {
|
|
|
|
$obj = new ObjectTest_ExtensionTest2();
|
|
|
|
|
|
|
|
$this->assertTrue($obj->hasExtension('ObjectTest_Extension'));
|
|
|
|
$this->assertTrue($obj->extInstance('ObjectTest_Extension')->is_a('ObjectTest_Extension'));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCacheToFile() {
|
2009-03-16 07:49:05 +01:00
|
|
|
/*
|
|
|
|
// This doesn't run properly on our build slave.
|
2009-03-14 01:16:32 +01:00
|
|
|
$obj = new ObjectTest_CacheTest();
|
|
|
|
|
2009-03-15 02:09:59 +01:00
|
|
|
$obj->clearCache('cacheMethod');
|
|
|
|
$obj->clearCache('cacheMethod', null, array(true));
|
|
|
|
$obj->clearCache('incNumber');
|
|
|
|
|
2009-03-15 01:48:33 +01:00
|
|
|
$this->assertEquals('noarg', $obj->cacheToFile('cacheMethod', -1));
|
|
|
|
$this->assertEquals('hasarg', $obj->cacheToFile('cacheMethod', -1, null, array(true)));
|
|
|
|
$this->assertEquals('hasarg', $obj->cacheToFile('cacheMethod', 3600, null, array(true)));
|
|
|
|
|
|
|
|
// -1 lifetime will ensure that the cache isn't read - number incremented
|
|
|
|
$this->assertEquals(1, $obj->cacheToFile('incNumber', -1));
|
|
|
|
// -1 lifetime will ensure that the cache isn't read - number incremented
|
|
|
|
$this->assertEquals(2, $obj->cacheToFile('incNumber', -1));
|
|
|
|
// Number shouldn't be incremented now because we're using the cached version
|
2009-03-15 02:09:59 +01:00
|
|
|
$this->assertEquals(2, $obj->cacheToFile('incNumber'));
|
2009-03-16 07:49:05 +01:00
|
|
|
*/
|
2009-03-14 01:16:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testExtend() {
|
|
|
|
$object = new ObjectTest_ExtendTest();
|
|
|
|
$argument = 'test';
|
|
|
|
|
|
|
|
$this->assertEquals($object->extend('extendableMethod'), array('ExtendTest2()'));
|
|
|
|
$this->assertEquals($object->extend('extendableMethod', $argument), array('ExtendTest2(modified)'));
|
|
|
|
$this->assertEquals($argument, 'modified');
|
|
|
|
|
|
|
|
$this->assertEquals($object->invokeWithExtensions('extendableMethod'), array('ExtendTest()', 'ExtendTest2()'));
|
|
|
|
$this->assertEquals (
|
|
|
|
$object->invokeWithExtensions('extendableMethod', 'test'),
|
|
|
|
array('ExtendTest(test)', 'ExtendTest2(modified)')
|
2008-10-15 19:05:46 +02:00
|
|
|
);
|
|
|
|
}
|
2009-03-14 01:16:32 +01:00
|
|
|
|
2008-03-19 21:39:07 +01:00
|
|
|
}
|
|
|
|
|
2009-03-14 01:16:32 +01:00
|
|
|
/**#@+
|
|
|
|
* @ignore
|
|
|
|
*/
|
|
|
|
|
2008-03-19 21:39:07 +01:00
|
|
|
class ObjectTest_T1A extends Object {
|
|
|
|
function testMethod() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
function otherMethod() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_T1B extends Object {
|
|
|
|
function someMethod() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_T1C extends Object {
|
|
|
|
function t1cMethod() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_T2 extends Object {
|
|
|
|
protected $failover;
|
|
|
|
protected $failoverArr = array();
|
|
|
|
|
|
|
|
function __construct() {
|
|
|
|
$this->failover = new ObjectTest_T1A();
|
|
|
|
$this->failoverArr[0] = new ObjectTest_T1B();
|
|
|
|
$this->failoverArr[1] = new ObjectTest_T1C();
|
|
|
|
|
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
|
|
|
function defineMethods() {
|
|
|
|
$this->addWrapperMethod('Wrapping', 'wrappedMethod');
|
|
|
|
|
|
|
|
$this->addMethodsFrom('failover');
|
|
|
|
$this->addMethodsFrom('failoverArr',0);
|
|
|
|
$this->addMethodsFrom('failoverArr',1);
|
|
|
|
|
|
|
|
$this->createMethod('testCreateMethod', 'return "created";');
|
|
|
|
}
|
|
|
|
|
|
|
|
function wrappedMethod($val) {
|
|
|
|
return $val;
|
|
|
|
}
|
|
|
|
|
|
|
|
function normalMethod() {
|
|
|
|
return true;
|
2008-03-19 21:38:58 +01:00
|
|
|
}
|
|
|
|
|
2008-03-19 21:39:07 +01:00
|
|
|
}
|
2008-10-03 17:57:32 +02:00
|
|
|
|
|
|
|
class ObjectTest_MyObject extends Object {
|
|
|
|
public $title = 'my object';
|
2008-10-15 19:05:46 +02:00
|
|
|
static $mystaticProperty = "MyObject";
|
|
|
|
static $mystaticArray = array('one');
|
2008-10-03 17:57:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_MySubObject extends ObjectTest_MyObject {
|
|
|
|
public $title = 'my subobject';
|
2008-10-15 19:05:46 +02:00
|
|
|
static $mystaticProperty = "MySubObject";
|
|
|
|
static $mystaticSubProperty = "MySubObject";
|
|
|
|
static $mystaticArray = array('two');
|
2008-10-03 17:57:32 +02:00
|
|
|
}
|
2009-03-14 01:16:32 +01:00
|
|
|
|
|
|
|
class ObjectTest_CreateTest extends Object {
|
|
|
|
|
|
|
|
public $constructArguments;
|
|
|
|
|
|
|
|
public function __construct() {
|
|
|
|
$this->constructArguments = func_get_args();
|
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_CreateTest2 extends Object {}
|
|
|
|
class ObjectTest_CreateTest3 extends Object {}
|
|
|
|
|
|
|
|
class ObjectTest_ExtensionTest extends Object {
|
|
|
|
|
|
|
|
public static $extensions = array (
|
|
|
|
'HiErAcHy',
|
|
|
|
"TrAnSlAtAbLe('FOO', 'BAR')",
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_ExtensionTest2 extends Object {
|
|
|
|
public static $extensions = array('ObjectTest_Extension');
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_Extension extends Extension {}
|
|
|
|
|
|
|
|
class ObjectTest_CacheTest extends Object {
|
|
|
|
|
|
|
|
public $count = 0;
|
|
|
|
|
|
|
|
public function cacheMethod($arg1 = null) {
|
|
|
|
return ($arg1) ? 'hasarg' : 'noarg';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function incNumber() {
|
|
|
|
$this->count++;
|
|
|
|
return $this->count;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_ExtendTest extends Object {
|
|
|
|
public static $extensions = array('ObjectTest_ExtendTest1', 'ObjectTest_ExtendTest2');
|
|
|
|
public function extendableMethod($argument = null) { return "ExtendTest($argument)"; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_ExtendTest1 extends Extension {
|
|
|
|
public function extendableMethod(&$argument = null) {
|
|
|
|
if($argument) $argument = 'modified';
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ObjectTest_ExtendTest2 extends Extension {
|
|
|
|
public function extendableMethod($argument = null) { return "ExtendTest2($argument)"; }
|
|
|
|
}
|
|
|
|
|
|
|
|
/**#@-*/
|