mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 14:46:19 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			452 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			452 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
namespace yiiunit\framework\base;
 | 
						|
 | 
						|
use yii\base\Behavior;
 | 
						|
use yii\base\Component;
 | 
						|
use yii\base\Event;
 | 
						|
use yiiunit\TestCase;
 | 
						|
 | 
						|
function globalEventHandler($event)
 | 
						|
{
 | 
						|
    $event->sender->eventHandled = true;
 | 
						|
}
 | 
						|
 | 
						|
function globalEventHandler2($event)
 | 
						|
{
 | 
						|
    $event->sender->eventHandled = true;
 | 
						|
    $event->handled = true;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @group base
 | 
						|
 */
 | 
						|
class ComponentTest extends TestCase
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var NewComponent
 | 
						|
     */
 | 
						|
    protected $component;
 | 
						|
 | 
						|
    protected function setUp()
 | 
						|
    {
 | 
						|
        parent::setUp();
 | 
						|
        $this->mockApplication();
 | 
						|
        $this->component = new NewComponent();
 | 
						|
    }
 | 
						|
 | 
						|
    protected function tearDown()
 | 
						|
    {
 | 
						|
        parent::tearDown();
 | 
						|
        $this->component = null;
 | 
						|
    }
 | 
						|
 | 
						|
    public function testClone()
 | 
						|
    {
 | 
						|
        $component = new NewComponent();
 | 
						|
        $behavior = new NewBehavior();
 | 
						|
        $component->attachBehavior('a', $behavior);
 | 
						|
        $this->assertSame($behavior, $component->getBehavior('a'));
 | 
						|
        $component->on('test', 'fake');
 | 
						|
        $this->assertTrue($component->hasEventHandlers('test'));
 | 
						|
 | 
						|
        $clone = clone $component;
 | 
						|
        $this->assertNotSame($component, $clone);
 | 
						|
        $this->assertNull($clone->getBehavior('a'));
 | 
						|
        $this->assertFalse($clone->hasEventHandlers('test'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testHasProperty()
 | 
						|
    {
 | 
						|
        $this->assertTrue($this->component->hasProperty('Text'));
 | 
						|
        $this->assertTrue($this->component->hasProperty('text'));
 | 
						|
        $this->assertFalse($this->component->hasProperty('Caption'));
 | 
						|
        $this->assertTrue($this->component->hasProperty('content'));
 | 
						|
        $this->assertFalse($this->component->hasProperty('content', false));
 | 
						|
        $this->assertFalse($this->component->hasProperty('Content'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testCanGetProperty()
 | 
						|
    {
 | 
						|
        $this->assertTrue($this->component->canGetProperty('Text'));
 | 
						|
        $this->assertTrue($this->component->canGetProperty('text'));
 | 
						|
        $this->assertFalse($this->component->canGetProperty('Caption'));
 | 
						|
        $this->assertTrue($this->component->canGetProperty('content'));
 | 
						|
        $this->assertFalse($this->component->canGetProperty('content', false));
 | 
						|
        $this->assertFalse($this->component->canGetProperty('Content'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testCanSetProperty()
 | 
						|
    {
 | 
						|
        $this->assertTrue($this->component->canSetProperty('Text'));
 | 
						|
        $this->assertTrue($this->component->canSetProperty('text'));
 | 
						|
        $this->assertFalse($this->component->canSetProperty('Object'));
 | 
						|
        $this->assertFalse($this->component->canSetProperty('Caption'));
 | 
						|
        $this->assertTrue($this->component->canSetProperty('content'));
 | 
						|
        $this->assertFalse($this->component->canSetProperty('content', false));
 | 
						|
        $this->assertFalse($this->component->canSetProperty('Content'));
 | 
						|
 | 
						|
        // behavior
 | 
						|
        $this->assertFalse($this->component->canSetProperty('p2'));
 | 
						|
        $behavior = new NewBehavior();
 | 
						|
        $this->component->attachBehavior('a', $behavior);
 | 
						|
        $this->assertTrue($this->component->canSetProperty('p2'));
 | 
						|
        $this->component->detachBehavior('a');
 | 
						|
    }
 | 
						|
 | 
						|
    public function testGetProperty()
 | 
						|
    {
 | 
						|
        $this->assertTrue('default' === $this->component->Text);
 | 
						|
        $this->setExpectedException('yii\base\UnknownPropertyException');
 | 
						|
        $value2 = $this->component->Caption;
 | 
						|
    }
 | 
						|
 | 
						|
    public function testSetProperty()
 | 
						|
    {
 | 
						|
        $value = 'new value';
 | 
						|
        $this->component->Text = $value;
 | 
						|
        $this->assertEquals($value, $this->component->Text);
 | 
						|
        $this->setExpectedException('yii\base\UnknownPropertyException');
 | 
						|
        $this->component->NewMember = $value;
 | 
						|
    }
 | 
						|
 | 
						|
    public function testIsset()
 | 
						|
    {
 | 
						|
        $this->assertTrue(isset($this->component->Text));
 | 
						|
        $this->assertFalse(empty($this->component->Text));
 | 
						|
 | 
						|
        $this->component->Text = '';
 | 
						|
        $this->assertTrue(isset($this->component->Text));
 | 
						|
        $this->assertTrue(empty($this->component->Text));
 | 
						|
 | 
						|
        $this->component->Text = null;
 | 
						|
        $this->assertFalse(isset($this->component->Text));
 | 
						|
        $this->assertTrue(empty($this->component->Text));
 | 
						|
 | 
						|
        $this->assertFalse(isset($this->component->p2));
 | 
						|
        $this->component->attachBehavior('a', new NewBehavior());
 | 
						|
        $this->component->setP2('test');
 | 
						|
        $this->assertTrue(isset($this->component->p2));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testCallUnknownMethod()
 | 
						|
    {
 | 
						|
        $this->setExpectedException('yii\base\UnknownMethodException');
 | 
						|
        $this->component->unknownMethod();
 | 
						|
    }
 | 
						|
 | 
						|
    public function testUnset()
 | 
						|
    {
 | 
						|
        unset($this->component->Text);
 | 
						|
        $this->assertFalse(isset($this->component->Text));
 | 
						|
        $this->assertTrue(empty($this->component->Text));
 | 
						|
 | 
						|
        $this->component->attachBehavior('a', new NewBehavior());
 | 
						|
        $this->component->setP2('test');
 | 
						|
        $this->assertEquals('test', $this->component->getP2());
 | 
						|
 | 
						|
        unset($this->component->p2);
 | 
						|
        $this->assertNull($this->component->getP2());
 | 
						|
    }
 | 
						|
 | 
						|
    public function testUnsetReadonly()
 | 
						|
    {
 | 
						|
        $this->setExpectedException('yii\base\InvalidCallException');
 | 
						|
        unset($this->component->object);
 | 
						|
    }
 | 
						|
 | 
						|
    public function testOn()
 | 
						|
    {
 | 
						|
        $this->assertFalse($this->component->hasEventHandlers('click'));
 | 
						|
        $this->component->on('click', 'foo');
 | 
						|
        $this->assertTrue($this->component->hasEventHandlers('click'));
 | 
						|
 | 
						|
        $this->assertFalse($this->component->hasEventHandlers('click2'));
 | 
						|
        $p = 'on click2';
 | 
						|
        $this->component->$p = 'foo2';
 | 
						|
        $this->assertTrue($this->component->hasEventHandlers('click2'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testOff()
 | 
						|
    {
 | 
						|
        $this->assertFalse($this->component->hasEventHandlers('click'));
 | 
						|
        $this->component->on('click', 'foo');
 | 
						|
        $this->assertTrue($this->component->hasEventHandlers('click'));
 | 
						|
        $this->component->off('click', 'foo');
 | 
						|
        $this->assertFalse($this->component->hasEventHandlers('click'));
 | 
						|
 | 
						|
        $this->component->on('click2', 'foo');
 | 
						|
        $this->component->on('click2', 'foo2');
 | 
						|
        $this->component->on('click2', 'foo3');
 | 
						|
        $this->assertTrue($this->component->hasEventHandlers('click2'));
 | 
						|
        $this->component->off('click2', 'foo3');
 | 
						|
        $this->assertTrue($this->component->hasEventHandlers('click2'));
 | 
						|
        $this->component->off('click2');
 | 
						|
        $this->assertFalse($this->component->hasEventHandlers('click2'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testTrigger()
 | 
						|
    {
 | 
						|
        $this->component->on('click', [$this->component, 'myEventHandler']);
 | 
						|
        $this->assertFalse($this->component->eventHandled);
 | 
						|
        $this->assertNull($this->component->event);
 | 
						|
        $this->component->raiseEvent();
 | 
						|
        $this->assertTrue($this->component->eventHandled);
 | 
						|
        $this->assertEquals('click', $this->component->event->name);
 | 
						|
        $this->assertEquals($this->component, $this->component->event->sender);
 | 
						|
        $this->assertFalse($this->component->event->handled);
 | 
						|
 | 
						|
        $eventRaised = false;
 | 
						|
        $this->component->on('click', function ($event) use (&$eventRaised) {
 | 
						|
            $eventRaised = true;
 | 
						|
        });
 | 
						|
        $this->component->raiseEvent();
 | 
						|
        $this->assertTrue($eventRaised);
 | 
						|
 | 
						|
        // raise event w/o parameters
 | 
						|
        $eventRaised = false;
 | 
						|
        $this->component->on('test', function ($event) use (&$eventRaised) {
 | 
						|
            $eventRaised = true;
 | 
						|
        });
 | 
						|
        $this->component->trigger('test');
 | 
						|
        $this->assertTrue($eventRaised);
 | 
						|
    }
 | 
						|
 | 
						|
    public function testHasEventHandlers()
 | 
						|
    {
 | 
						|
        $this->assertFalse($this->component->hasEventHandlers('click'));
 | 
						|
        $this->component->on('click', 'foo');
 | 
						|
        $this->assertTrue($this->component->hasEventHandlers('click'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testStopEvent()
 | 
						|
    {
 | 
						|
        $component = new NewComponent;
 | 
						|
        $component->on('click', 'yiiunit\framework\base\globalEventHandler2');
 | 
						|
        $component->on('click', [$this->component, 'myEventHandler']);
 | 
						|
        $component->raiseEvent();
 | 
						|
        $this->assertTrue($component->eventHandled);
 | 
						|
        $this->assertFalse($this->component->eventHandled);
 | 
						|
    }
 | 
						|
 | 
						|
    public function testAttachBehavior()
 | 
						|
    {
 | 
						|
        $component = new NewComponent;
 | 
						|
        $this->assertFalse($component->hasProperty('p'));
 | 
						|
        $this->assertFalse($component->behaviorCalled);
 | 
						|
        $this->assertNull($component->getBehavior('a'));
 | 
						|
 | 
						|
        $behavior = new NewBehavior;
 | 
						|
        $component->attachBehavior('a', $behavior);
 | 
						|
        $this->assertSame($behavior, $component->getBehavior('a'));
 | 
						|
        $this->assertTrue($component->hasProperty('p'));
 | 
						|
        $component->test();
 | 
						|
        $this->assertTrue($component->behaviorCalled);
 | 
						|
 | 
						|
        $this->assertSame($behavior, $component->detachBehavior('a'));
 | 
						|
        $this->assertFalse($component->hasProperty('p'));
 | 
						|
        $this->setExpectedException('yii\base\UnknownMethodException');
 | 
						|
        $component->test();
 | 
						|
 | 
						|
        $p = 'as b';
 | 
						|
        $component = new NewComponent;
 | 
						|
        $component->$p = ['class' => 'NewBehavior'];
 | 
						|
        $this->assertSame($behavior, $component->getBehavior('a'));
 | 
						|
        $this->assertTrue($component->hasProperty('p'));
 | 
						|
        $component->test();
 | 
						|
        $this->assertTrue($component->behaviorCalled);
 | 
						|
    }
 | 
						|
 | 
						|
    public function testAttachBehaviors()
 | 
						|
    {
 | 
						|
        $component = new NewComponent;
 | 
						|
        $this->assertNull($component->getBehavior('a'));
 | 
						|
        $this->assertNull($component->getBehavior('b'));
 | 
						|
 | 
						|
        $behavior = new NewBehavior;
 | 
						|
 | 
						|
        $component->attachBehaviors([
 | 
						|
            'a' => $behavior,
 | 
						|
            'b' => $behavior,
 | 
						|
        ]);
 | 
						|
 | 
						|
        $this->assertSame(['a' => $behavior, 'b' => $behavior], $component->getBehaviors());
 | 
						|
    }
 | 
						|
 | 
						|
    public function testDetachBehavior()
 | 
						|
    {
 | 
						|
        $component = new NewComponent;
 | 
						|
        $behavior = new NewBehavior;
 | 
						|
 | 
						|
        $component->attachBehavior('a', $behavior);
 | 
						|
        $this->assertSame($behavior, $component->getBehavior('a'));
 | 
						|
 | 
						|
        $detachedBehavior = $component->detachBehavior('a');
 | 
						|
        $this->assertSame($detachedBehavior, $behavior);
 | 
						|
        $this->assertNull($component->getBehavior('a'));
 | 
						|
 | 
						|
        $detachedBehavior = $component->detachBehavior('z');
 | 
						|
        $this->assertNull($detachedBehavior);
 | 
						|
    }
 | 
						|
 | 
						|
    public function testDetachBehaviors()
 | 
						|
    {
 | 
						|
        $component = new NewComponent;
 | 
						|
        $behavior = new NewBehavior;
 | 
						|
 | 
						|
        $component->attachBehavior('a', $behavior);
 | 
						|
        $this->assertSame($behavior, $component->getBehavior('a'));
 | 
						|
        $component->attachBehavior('b', $behavior);
 | 
						|
        $this->assertSame($behavior, $component->getBehavior('b'));
 | 
						|
 | 
						|
        $component->detachBehaviors();
 | 
						|
        $this->assertNull($component->getBehavior('a'));
 | 
						|
        $this->assertNull($component->getBehavior('b'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testSetReadOnlyProperty()
 | 
						|
    {
 | 
						|
        $this->setExpectedException(
 | 
						|
            '\yii\base\InvalidCallException',
 | 
						|
            'Setting read-only property: yiiunit\framework\base\NewComponent::object'
 | 
						|
        );
 | 
						|
        $this->component->object = 'z';
 | 
						|
    }
 | 
						|
 | 
						|
    public function testSetPropertyOfBehavior()
 | 
						|
    {
 | 
						|
        $this->assertNull($this->component->getBehavior('a'));
 | 
						|
 | 
						|
        $behavior = new NewBehavior;
 | 
						|
        $this->component->attachBehaviors([
 | 
						|
            'a' => $behavior,
 | 
						|
        ]);
 | 
						|
        $this->component->p = 'Yii is cool.';
 | 
						|
 | 
						|
        $this->assertSame('Yii is cool.', $this->component->getBehavior('a')->p);
 | 
						|
    }
 | 
						|
 | 
						|
    public function testSettingBehaviorWithSetter()
 | 
						|
    {
 | 
						|
        $behaviorName = 'foo';
 | 
						|
        $this->assertNull($this->component->getBehavior($behaviorName));
 | 
						|
        $p = 'as ' . $behaviorName;
 | 
						|
        $this->component->$p = __NAMESPACE__ .  '\NewBehavior';
 | 
						|
        $this->assertSame(__NAMESPACE__ .  '\NewBehavior', get_class($this->component->getBehavior($behaviorName)));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testWriteOnlyProperty()
 | 
						|
    {
 | 
						|
        $this->setExpectedException(
 | 
						|
            '\yii\base\InvalidCallException',
 | 
						|
            'Getting write-only property: yiiunit\framework\base\NewComponent::writeOnly'
 | 
						|
        );
 | 
						|
        $this->component->writeOnly;
 | 
						|
    }
 | 
						|
 | 
						|
    public function testSuccessfulMethodCheck()
 | 
						|
    {
 | 
						|
        $this->assertTrue($this->component->hasMethod('hasProperty'));
 | 
						|
    }
 | 
						|
 | 
						|
    public function testTurningOffNonExistingBehavior()
 | 
						|
    {
 | 
						|
        $this->assertFalse($this->component->hasEventHandlers('foo'));
 | 
						|
        $this->assertFalse($this->component->off('foo'));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
class NewComponent extends Component
 | 
						|
{
 | 
						|
    private $_object = null;
 | 
						|
    private $_text = 'default';
 | 
						|
    private $_items = [];
 | 
						|
    public $content;
 | 
						|
 | 
						|
    public function getText()
 | 
						|
    {
 | 
						|
        return $this->_text;
 | 
						|
    }
 | 
						|
 | 
						|
    public function setText($value)
 | 
						|
    {
 | 
						|
        $this->_text = $value;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getObject()
 | 
						|
    {
 | 
						|
        if (!$this->_object) {
 | 
						|
            $this->_object = new self;
 | 
						|
            $this->_object->_text = 'object text';
 | 
						|
        }
 | 
						|
 | 
						|
        return $this->_object;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getExecute()
 | 
						|
    {
 | 
						|
        return function ($param) {
 | 
						|
            return $param * 2;
 | 
						|
        };
 | 
						|
    }
 | 
						|
 | 
						|
    public function getItems()
 | 
						|
    {
 | 
						|
        return $this->_items;
 | 
						|
    }
 | 
						|
 | 
						|
    public $eventHandled = false;
 | 
						|
    public $event;
 | 
						|
    public $behaviorCalled = false;
 | 
						|
 | 
						|
    public function myEventHandler($event)
 | 
						|
    {
 | 
						|
        $this->eventHandled = true;
 | 
						|
        $this->event = $event;
 | 
						|
    }
 | 
						|
 | 
						|
    public function raiseEvent()
 | 
						|
    {
 | 
						|
        $this->trigger('click', new Event);
 | 
						|
    }
 | 
						|
 | 
						|
    public function setWriteOnly()
 | 
						|
    {
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
class NewBehavior extends Behavior
 | 
						|
{
 | 
						|
    public $p;
 | 
						|
    private $p2;
 | 
						|
 | 
						|
    public function getP2()
 | 
						|
    {
 | 
						|
        return $this->p2;
 | 
						|
    }
 | 
						|
 | 
						|
    public function setP2($value)
 | 
						|
    {
 | 
						|
        $this->p2 = $value;
 | 
						|
    }
 | 
						|
 | 
						|
    public function test()
 | 
						|
    {
 | 
						|
        $this->owner->behaviorCalled = true;
 | 
						|
 | 
						|
        return 2;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
class NewComponent2 extends Component
 | 
						|
{
 | 
						|
    public $a;
 | 
						|
    public $b;
 | 
						|
    public $c;
 | 
						|
 | 
						|
    public function __construct($b, $c)
 | 
						|
    {
 | 
						|
        $this->b = $b;
 | 
						|
        $this->c = $c;
 | 
						|
    }
 | 
						|
}
 |