<?php
/*
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage UnitTests
 * @since 2011-10-06
 * 
 * Unit tests for CliLogger class
 */

require_once dirname(__FILE__) . '/../../Registry.php';
require_once dirname(__FILE__) . '/../../Config.php';
require_once dirname(__FILE__) . '/../../exception/GeneralException.php';
require_once dirname(__FILE__) . '/../../logger/Logger.php';
require_once dirname(__FILE__) . '/../../logger/FileLogger.php';
require_once 'vfsStream/vfsStream.php';

class FileLoggerTest extends PHPUnit_Framework_TestCase
{

    protected $conf;
    
    public function run(PHPUnit_Framework_TestResult $result = NULL)
    {
        $this->setPreserveGlobalState(false);
        return parent::run($result);
    }

    public function setUp()
    {
        vfsStreamWrapper::register();
        vfsStream::setup();
        $root = vfsStream::create(array());
        vfsStreamWrapper::setRoot($root);
        Config::set('LOGGING', true);
        $this->conf = array('logger' => 'FileLogger', 'filepath' => vfsStream::url('root/log.txt'));
        Config::set('Logger', $this->conf);
        if ($root->hasChild('log.txt')) {
            $root->removeChild('log.txt');
        }
    }

    /**
     * @runInSeparateProcess
     */
    public function testGetInstance()
    {
        $logger = Logger::getInstance();
        $this->assertInstanceOf('FileLogger', $logger);
    }

    /**
     * @runInSeparateProcess
     */
    public function testCannotWrite()
    {
        Config::set('DEBUG', true);
        $conf = array('logger' => 'FileLogger', 'filepath' => '/log.txt');
        Config::set('Logger', $conf);

        $this->setExpectedException('GeneralException', 'Could not open file /log.txt');
        
        $logger = Logger::getInstance()->log('new msg');
        $this->assertFileNotExists('log.txt');
    }

    /**
     * @runInSeparateProcess
     */
    public function testLog()
    {
        Config::set('DEBUG', true);
        $this->assertFileNotExists($this->conf['filepath']);
        $logger = Logger::getInstance();
        $logger->setPid(123);
        $logger->log('new msg');
        $this->assertFileExists($this->conf['filepath']);
    }

    /**
     * @runInSeparateProcess
     */
    public function testDestruct()
    {
        Config::set('DEBUG', true);
        $my_pid = posix_getpid();
        $fd_command = 'lsof -n -p ' . $my_pid . ' | wc -l';
        $fd_count_start = (int) `$fd_command`;
        $logger = Logger::getInstance();
        $logger->log('new msg');
        $logger->log('new msg');
        $logger->log('new msg');
        $logger->log('new msg');
        $logger->log('new msg');
        $logger->log('new msg');
        $logger->log('new msg');
        $logger->log('new msg');
        $logger->__destruct();
        $this->assertAttributeEquals(null, 'handler', $logger);
        $fd_count_end = (int) `$fd_command`;
        $this->assertSame($fd_count_start, $fd_count_end);
    }

    public function tearDown()
    {
        $conf = Config::getInstance();
        $conf->offsetUnset('Logger');
        if (file_exists($this->conf['filepath'])) {
            unlink($this->conf['filepath']);
        }
    }
}