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

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

    protected function setUp()
    {
        $this->_object = Core_Console_Application::getInstance();
    }

    protected function tearDown()
    {
        Core_Console_Application::resetInstance();
    }

    /**
     * @covers Core_Console_Application::getInstance
     * @runInSeparateProcess
     */
    public function testCanGetInstance()
    {
        $this->assertInstanceOf('Core_Console_Application', Core_Console_Application::getInstance());
    }

    /**
     * @covers Core_Console_Application::getInstance
     * @group runkit
     * @group pecl
     */
    public function testRunningConsoleApplicationOutsideConsoleRuntimeThrowsARuntimeException()
    {
        if (!function_exists('runkit_function_add')) {
            $this->markTestSkipped('Requires the runkit_function_add() provided by "runkit" PECL');
        } else if (!ini_get('runkit.internal_override')) {
            $this->markTestSkipped('Requires PHP INI setting runkit.internal_override = true');
        }
        runkit_function_rename('php_sapi_name', 'php_sapi_name_old');
        runkit_function_add('php_sapi_name', '', 'return "apache2handler";');

        try {
            Core_Console_Application::getInstance();

            // we've failed if we're here
            $this->fail();
        } catch (RuntimeException $exception) {
            $this->assertTrue(true);
        }
        runkit_function_remove('php_sapi_name');
        runkit_function_rename('php_sapi_name_old', 'php_sapi_name');
    }

    /**
     * @covers Core_Console_Application::setInteraction
     * @covers Core_Console_Application::isInteraction
     */
    public function testCanSetAndGetInteraction()
    {
        $this->_object->setInteraction(true);
        $this->assertTrue($this->_object->isInteraction());
    }

    /**
     * @covers Core_Console_Application::isInteraction
     */
    public function testInteractionIsDetectedFromShellRuntime()
    {
        exec('[[ -t 0 ]]', $output, $retval);

        $this->assertEquals(!$retval, $this->_object->isInteraction());
    }

    /**
     * @covers Core_Console_Application::isColor
     */
    public function testColorWilNotBeEnabledWhenNonInteractive()
    {
        $this->_object
            ->setInteraction(false)
            ->setColor(true);

        $this->assertFalse($this->_object->isColor());
    }

    /**
     * @covers Core_Console_Application::setColor
     * @covers Core_Console_Application::isColor
     *
     * @depends testColorWilNotBeEnabledWhenNonInteractive
     */
    public function testCanSetAndGetColor()
    {
        $this->_object
            ->setInteraction(true)
            ->setColor(true);

        $this->assertTrue($this->_object->isColor());
    }

    /**
     * @covers Core_Console_Application::isColor
     *
     * @depends testColorWilNotBeEnabledWhenNonInteractive
     */
    public function testColorIsDetectedFromShellRuntimeForDumbTerminal()
    {
        putenv('TERM=dumb');
        $this->_object
            ->setInteraction(true);

        $this->assertFalse($this->_object->isColor());
    }

    /**
     * @covers Core_Console_Application::isColor
     *
     * @depends testColorWilNotBeEnabledWhenNonInteractive
     */
    public function testColorIsDetectedFromShellRuntimeForNonDumbTerminal()
    {
        putenv('TERM=xterm');
        $this->_object
            ->setInteraction(true);

        $this->assertTrue($this->_object->isColor());
    }

    /**
     * @covers Core_Console_Application::setQuiet
     * @covers Core_Console_Application::isQuiet
     */
    public function testCanSetAndGetQuiet()
    {
        $this->_object->setQuiet(true);
        $this->assertTrue($this->_object->isQuiet());
    }

    /**
     * @covers Core_Console_Application::isQuiet
     */
    public function testApplicationIsNotQuietByDefault()
    {
        $this->assertFalse($this->_object->isQuiet());
    }

    /**
     * @covers Core_Console_Application::setVerbose
     * @covers Core_Console_Application::isVerbose
     */
    public function testCanSetAndGetVerbose()
    {
        $this->_object->setVerbose(true);
        $this->assertTrue($this->_object->isVerbose());
    }

    /**
     * @covers Core_Console_Application::isVerbose
     */
    public function testApplicationIsNotVerboseByDefault()
    {
        $this->assertFalse($this->_object->isVerbose());
    }

    /**
     * @covers Core_Console_Application::isVerbose
     */
    public function testQuietApplicationIsNotVerbose()
    {
        $this->_object
            ->setVerbose(true)
            ->setQuiet(true);

        $this->assertFalse($this->_object->isVerbose());
    }

    /**
     * @covers Core_Console_Application::isQuiet
     */
    public function testVerboseApplicationIsNotQuiet()
    {
        $this->_object
            ->setQuiet(true)
            ->setVerbose(true);

        $this->assertFalse($this->_object->isQuiet());
    }
}
