<?php
/**
 * core.framework
 *
 * @category   Core
 * @package    Core_Form
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 */

/**
 * @category   Core
 * @package    Core_Form
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 * @group      Core_Form
 */
class Core_Form_Element_CollectionTest extends CoreTest_Container_TestCase
{
    /**
     * @var Core_Form_Element_Collection
     */
    protected $_object;

    protected function setUp()
    {
        $this->_object = new Core_Form_Element_Collection;
    }

    /**
     * @covers Core_Form_Element_Collection::getElements
     */
    public function testCanFetchElements()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('_getItems'));
        $object
            ->expects($this->once())
            ->method('_getItems');
        $object->getElements();
    }

    /**
     * @covers Core_Form_Element_Collection::getElement
     */
    public function testCanFetchElement()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('_getItem'));
        $object
            ->expects($this->once())
            ->method('_getItem')
            ->with($this->equalTo('foo'));

        $object->getElement('foo');
    }

    /**
     * @covers Core_Form_Element_Collection::setRawValue
     */
    public function testSetRawValueWillProxyToPopulateRaw()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('populateRaw'));
        $object
            ->expects($this->once())
            ->method('populateRaw')
            ->with($this->equalTo(array('a', 'b')));

        $object->setRawValue(array('a', 'b'));
    }

    /**
     * @covers Core_Form_Element_Collection::setRawValue
     */
    public function testSettingAndEmptyRawValueWillConvertToArray()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('populateRaw'));
        $object
            ->expects($this->once())
            ->method('populateRaw')
            ->with($this->equalTo(array()));

        $object->setRawValue('');
    }

    /**
     * @covers Core_Form_Element_Collection::getRawValue
     */
    public function testGetRawValueWillProxyToGetRawValues()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('getRawValues'));
        $object
            ->expects($this->once())
            ->method('getRawValues')
            ->will($this->returnValue(array('a', 'b')));

        $this->assertEquals(array('a', 'b'), $object->getRawValue());
    }

    /**
     * @covers Core_Form_Element_Collection::setValue
     */
    public function testSetValueWillProxyToPopulate()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('populate'));
        $object
            ->expects($this->once())
            ->method('populate')
            ->with($this->equalTo(array('a', 'b')));

        $object->setValue(array('a', 'b'));
    }

    /**
     * @covers Core_Form_Element_Collection::setValue
     */
    public function testSettingAndEmptyValueWillConvertToArray()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('populate'));
        $object
            ->expects($this->once())
            ->method('populate')
            ->with($this->equalTo(array()));

        $object->setValue('');
    }

    /**
     * @covers Core_Form_Element_Collection::getValue
     */
    public function testGetValueWillProxyToGetValues()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('getValues'));
        $object
            ->expects($this->once())
            ->method('getValues')
            ->will($this->returnValue(array('a', 'b')));

        $this->assertEquals(array('a', 'b'), $object->getValue());
    }

    /**
     * @covers Core_Form_Element_Collection::getError
     */
    public function testGetErrorWillProxyToGetErrors()
    {
        $object = $this->getMock('Core_Form_Element_Collection', array('getErrors'));
        $object
            ->expects($this->once())
            ->method('getErrors')
            ->will($this->returnValue(array('error 1', 'error 2')));

        $this->assertEquals(array('error 1', 'error 2'), $object->getError());
    }

    /**
     * @covers Core_Form_Element_Collection::getErrorMessage
     */
    public function testGetErrorMessageWillProxyToPrototypeInstance()
    {
        $prototype = $this->getMock('Core_Form_Element_Abstract', array('getErrorMessage'));
        $prototype
            ->expects($this->once())
            ->method('getErrorMessage')
            ->will($this->returnValue('abc'));
        $this->_object->setPrototypeInstance($prototype);

        $this->assertEquals('abc', $this->_object->getErrorMessage());
    }

    /**
     * @covers Core_Form_Element_Collection::getLabel
     */
    public function testGetLabelWillProxyToPrototypeInstance()
    {
        $prototype = $this->getMock('Core_Form_Element_Abstract', array('getLabel'));
        $prototype
            ->expects($this->once())
            ->method('getLabel')
            ->will($this->returnValue('lbl'));
        $this->_object->setPrototypeInstance($prototype);

        $this->assertEquals('lbl', $this->_object->getLabel());
    }

    /**
     * @covers Core_Form_Element_Collection::getPlaceholder
     */
    public function testGetPlaceholderWillProxyToPrototypeInstance()
    {
        $prototype = $this->getMock('Core_Form_Element_Abstract', array('getPlaceholder'));
        $prototype
            ->expects($this->once())
            ->method('getPlaceholder')
            ->will($this->returnValue('place'));
        $this->_object->setPrototypeInstance($prototype);

        $this->assertEquals('place', $this->_object->getPlaceholder());
    }

    /**
     * @covers Core_Form_Element_Collection::isIgnored
     */
    public function testIsIgnoredWillProxyToPrototypeInstance()
    {
        $prototype = $this->getMock('Core_Form_Element_Abstract', array('isIgnored'));
        $prototype
            ->expects($this->once())
            ->method('isIgnored')
            ->will($this->returnValue('ignored'));
        $this->_object->setPrototypeInstance($prototype);

        $this->assertEquals('ignored', $this->_object->isIgnored());
    }

    /**
     * @covers Core_Form_Element_Collection::isRequired
     */
    public function testIsRequiredWillProxyToPrototypeInstance()
    {
        $prototype = $this->getMock('Core_Form_Element_Abstract', array('isRequired'));
        $prototype
            ->expects($this->once())
            ->method('isRequired')
            ->will($this->returnValue('required'));
        $this->_object->setPrototypeInstance($prototype);

        $this->assertEquals('required', $this->_object->isRequired());
    }

    /**
     * @covers Core_Form_Element_Collection::setTemplate
     * @covers Core_Form_Element_Collection::getTemplate
     */
    public function testCanSetAndGetTemplate()
    {
        $template = $this->getMock('Twig_TemplateInterface');
        $view     = $this->getMock('Twig_Environment', array('loadTemplate'));
        $view
            ->expects($this->once())
            ->method('loadTemplate')
            ->with($this->equalTo('my.tpl'))
            ->will($this->returnValue($template));
        $this->_object
            ->setView($view)
            ->setTemplate('my.tpl');

        $this->assertEquals($template, $this->_object->getTemplate());
    }

    /**
     * @covers Core_Form_Element_Collection::render
     */
    public function testCanRender()
    {
        $template = $this->getMockForAbstractClass('Twig_TemplateInterface', array(), '', true, true, true, array('render'));
        $template
            ->expects($this->once())
            ->method('render')
            ->with($this->equalTo(array('this' => $this->_object, 'macro' => 'foo', 'context' => Core_Form::CONTEXT_ANGULAR)))
            ->will($this->returnValue('<rendered/>'));
        $this->_object
            ->setMacro('foo')
            ->setTemplate($template);

        $this->assertEquals('<rendered/>', $this->_object->render(Core_Form::CONTEXT_ANGULAR));
    }

    /**
     * @covers Core_Form_Element_Collection::isInCollection
     */
    public function testNotInCollectionIfItHasNoParent()
    {
        $this->assertFalse($this->_object->isInCollection());
    }

    /**
     * @covers Core_Form_Element_Collection::isInCollection
     */
    public function testNotInCollectionIfParentHasNoParent()
    {
        $parent = $this->getMockForAbstractClass('Core_Form_Group_Abstract', array(), '', true, true, true, array('getParent'));

        $object = $this->getMockForAbstractClass('Core_Form_Element_Collection', array(), '', true, true, true, array('getParent'));
        $object
            ->expects($this->once())
            ->method('getParent')
            ->will($this->returnValue($parent));

        $this->assertFalse($object->isInCollection());
    }

    /**
     * @covers Core_Form_Element_Collection::isInCollection
     */
    public function testIsInCollectionIfParentHasIsInstanceOfCollection()
    {
        $grandparent = $this->getMockForAbstractClass('Core_Form_Group_Collection');

        $parent = $this->getMockForAbstractClass('Core_Form_Group_Abstract', array(), '', true, true, true, array('getParent'));
        $parent
            ->expects($this->once())
            ->method('getParent')
            ->will($this->returnValue($grandparent));

        $object = $this->getMockForAbstractClass('Core_Form_Element_Collection', array(), '', true, true, true, array('getParent'));
        $object
            ->expects($this->once())
            ->method('getParent')
            ->will($this->returnValue($parent));

        $this->assertTrue($object->isInCollection());
    }
}
