assertTrue($st->hasMethod('publish'), "Test SiteTree has publish"); $this->assertTrue($st->hasMethod('migrateVersion'), "Test SiteTree has migrateVersion"); /* This relationship should be case-insensitive, too */ $this->assertTrue($st->hasMethod('PuBliSh'), "Test SiteTree has PuBliSh"); $this->assertTrue($st->hasMethod('MiGratEVersIOn'), "Test SiteTree has MiGratEVersIOn"); /* In a similar manner, all of SiteTree's methods should be available on ContentController, because $failover is set */ $this->assertTrue($cc->hasMethod('canView'), "Test ContentController has canView"); $this->assertTrue($cc->hasMethod('linkorcurrent'), "Test ContentController has linkorcurrent"); /* This 'method copying' is transitive, so all of Versioned's methods should be available on ContentControler. * Once again, this is case-insensitive */ $this->assertTrue($cc->hasMethod('MiGratEVersIOn'), "Test ContentController has MiGratEVersIOn"); /* The above examples make use of SiteTree, Versioned and ContentController. Let's test defineMethods() more * directly, with some sample objects */ $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); $this->assertTrue($obj->hasMethod($method), "Test that obj#$i has method $method ($obj->class)"); $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"); } } 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'); } 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' ); } /** * 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() { /* // This doesn't run properly on our build slave. $obj = new ObjectTest_CacheTest(); $obj->clearCache('cacheMethod'); $obj->clearCache('cacheMethod', null, array(true)); $obj->clearCache('incNumber'); $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 $this->assertEquals(2, $obj->cacheToFile('incNumber')); */ } 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)') ); } } /**#@+ * @ignore */ 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; } } class ObjectTest_MyObject extends Object { public $title = 'my object'; static $mystaticProperty = "MyObject"; static $mystaticArray = array('one'); } class ObjectTest_MySubObject extends ObjectTest_MyObject { public $title = 'my subobject'; static $mystaticProperty = "MySubObject"; static $mystaticSubProperty = "MySubObject"; static $mystaticArray = array('two'); } 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)"; } } /**#@-*/