[limb-svn] r5811 - in 3.x/trunk/limb/core: src tests/cases

svn at limb-project.com svn at limb-project.com
Sat May 5 14:36:36 MSD 2007


Author: pachanga
Date: 2007-05-05 14:36:36 +0400 (Sat, 05 May 2007)
New Revision: 5811
URL: http://fisheye.limb-project.com/changelog/limb/?cs=5811

Added:
   3.x/trunk/limb/core/src/lmbMixable.class.php
   3.x/trunk/limb/core/src/lmbMixin.class.php
   3.x/trunk/limb/core/tests/cases/lmbMixableTest.class.php
Log:
-- experimental mixin emulation lmbMixable class added, it allows to dynamically extend behavior of the mixed object with mixins

Added: 3.x/trunk/limb/core/src/lmbMixable.class.php
===================================================================
--- 3.x/trunk/limb/core/src/lmbMixable.class.php	                        (rev 0)
+++ 3.x/trunk/limb/core/src/lmbMixable.class.php	2007-05-05 10:36:36 UTC (rev 5811)
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright  Copyright &copy; 2004-2007 BIT
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version    $Id$
+ * @package    core
+ */
+
+lmb_require('limb/core/src/lmbObject.class.php');
+
+class lmbMixable extends lmbObject
+{
+  protected $mixins = array();
+  protected $mixins_loaded = false;
+  protected $mixins_signatures = array();
+
+  function mixin($mixin)
+  {
+    $this->mixins[] = $mixin;
+  }
+
+  function __call($method, $args)
+  {
+    $this->_ensureSignatures();
+
+    if(!isset($this->mixins_signatures[$method]))
+      throw new lmbException('Mixable does not support method "' . $method . '" (no such signature)',
+                              array('method' => $method));
+
+
+    return call_user_func_array(array($this->mixins_signatures[$method], $method), $args);
+  }
+
+  protected function _ensureSignatures()
+  {
+    if($this->mixins_loaded)
+      return;
+
+    foreach($this->mixins as $mixin)
+    {
+      if(is_object($mixin))
+      {
+        $obj = $mixin;
+        $obj->setOwner($this);
+        $class = get_class($mixin);
+      }
+      else
+      {
+        $obj = new $mixin($this);
+        $class = $mixin;
+      }
+
+      foreach(get_class_methods($class) as $method)
+        $this->mixins_signatures[$method] = $obj;
+    }
+
+    $this->mixins_loaded = true;
+  }
+}
+?>

Added: 3.x/trunk/limb/core/src/lmbMixin.class.php
===================================================================
--- 3.x/trunk/limb/core/src/lmbMixin.class.php	                        (rev 0)
+++ 3.x/trunk/limb/core/src/lmbMixin.class.php	2007-05-05 10:36:36 UTC (rev 5811)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright  Copyright &copy; 2004-2007 BIT
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version    $Id$
+ * @package    core
+ */
+
+class lmbMixin
+{
+  protected $owner;
+
+  function __construct($owner = null)
+  {
+    $this->owner = $owner;
+  }
+
+  function setOwner($owner)
+  {
+    $this->owner = $owner;
+  }
+
+}
+?>

Added: 3.x/trunk/limb/core/tests/cases/lmbMixableTest.class.php
===================================================================
--- 3.x/trunk/limb/core/tests/cases/lmbMixableTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/core/tests/cases/lmbMixableTest.class.php	2007-05-05 10:36:36 UTC (rev 5811)
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright  Copyright &copy; 2004-2007 BIT
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version    $Id: lmbObjectTest.class.php 5567 2007-04-06 14:37:24Z serega $
+ * @package    core
+ */
+lmb_require('limb/core/src/lmbMixable.class.php');
+lmb_require('limb/core/src/lmbMixin.class.php');
+
+class FooMixin extends lmbMixin
+{
+  function foo()
+  {
+    return 'foo';
+  }
+}
+
+class BarMixin extends lmbMixin
+{
+  function bar()
+  {
+    return 'bar';
+  }
+}
+
+class OwnerCallingMixin extends lmbMixin
+{
+  function ownerMy()
+  {
+    return $this->owner->my();
+  }
+}
+
+class FooOverridingMixin extends lmbMixin
+{
+  function foo()
+  {
+    return 'overriden foo';
+  }
+}
+
+class MixableTestVersion extends lmbMixable
+{
+  function __construct($mixins)
+  {
+    $this->mixins = $mixins;
+  }
+
+  function my()
+  {
+    return 'my';
+  }
+}
+
+class lmbMixableTest extends UnitTestCase
+{
+  function testMixinObjects()
+  {
+    $mixed = new lmbMixable();
+    $mixed->mixin(new FooMixin());
+    $mixed->mixin(new BarMixin());
+    $this->assertEqual($mixed->foo(), 'foo');
+    $this->assertEqual($mixed->bar(), 'bar');
+  }
+
+  function testMixinClasses()
+  {
+    $mixed = new lmbMixable();
+    $mixed->mixin('FooMixin');
+    $mixed->mixin('BarMixin');
+    $this->assertEqual($mixed->foo(), 'foo');
+    $this->assertEqual($mixed->bar(), 'bar');
+  }
+
+  function testOwnerMethodInvokation()
+  {
+    $mixed = new MixableTestVersion(array('FooMixin', 'BarMixin'));
+    $this->assertEqual($mixed->my(), 'my'); //native method of mixable
+    $this->assertEqual($mixed->foo(), 'foo');
+    $this->assertEqual($mixed->bar(), 'bar');
+  }
+
+  function testCallOwnerFromMixinForObjects()
+  {
+    //we need to ensure owner is set in mixin
+    $mixed = new MixableTestVersion(array(new OwnerCallingMixin()));
+    $this->assertEqual($mixed->ownerMy(), 'my');
+  }
+
+  function testCallOwnerFromMixinForClasses()
+  {
+    //we need to ensure owner is set in mixin
+    $mixed = new MixableTestVersion(array('OwnerCallingMixin'));
+    $this->assertEqual($mixed->ownerMy(), 'my');
+  }
+
+  function testMixinsOverriding()
+  {
+    $mixed = new lmbMixable();
+    $mixed->mixin(new FooMixin());
+    $mixed->mixin(new FooOverridingMixin());
+    $this->assertEqual($mixed->foo(), 'overriden foo');
+  }
+
+  function testNoSuchMethodThrowsException()
+  {
+    $mixed = new lmbMixable();
+
+    try
+    {
+      $mixed->hey();
+      $this->assertFalse(true);
+    }
+    catch(lmbException $e){}
+  }
+}
+?>
\ No newline at end of file



More information about the limb-svn mailing list