<?php

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

require_once dirname(__FILE__) . '/../../Registry.php';
require_once dirname(__FILE__) . '/../../Config.php';
require_once dirname(__FILE__) . '/../../classes/Env.class.php';
require_once dirname(__FILE__) . '/../../i18n/I18N.php';
require_once dirname(__FILE__) . '/../../exception/InitializationException.php';


/**
 * @runTestsInSeparateProcesses
 */
class I18NTest extends PHPUnit_Framework_TestCase
{
    public function run(PHPUnit_Framework_TestResult $result = NULL)
    {
        $this->setConstants();
        $this->setPreserveGlobalState(false);
        return parent::run($result);
    }

    /**
     * @runInSeparateProcess
     */
    public function testInit()
    {
        $this->setConstants();

        Config::set('I18N', array('locales' => array('ru' => 'ru-ru', 'us' => 'en-us')));
        I18N::init();
        $this->assertAttributeEquals(array('ru' => 'ru-ru', 'us' => 'en-us'), 'locales', 'I18N');
        $this->assertAttributeEquals('ru-ru', 'locale', 'I18N');
    }


    public function testInitNoConfig()
    {
        Config::set('I18N', array('locales' => null));
        $this->setExpectedException('InitializationException');
        I18N::init();
    }

    /**
     * @runInSeparateProcess
     */
    public function testInitFullConfig()
    {
        $this->setConstants();

        Config::set('I18N', array('locales' => array('ru' => 'ru-ru', 'en' => 'en_US'), 'bidi' => 'bidivalue', 'default' => 'ru'));
        I18N::init();
        $this->assertAttributeEquals('ru-ru', 'locale', 'I18N');
        $this->assertAttributeEquals('bidivalue', 'bidi', 'I18N');
        $this->assertAttributeEquals('ru', 'default', 'I18N');
    }

    /**
     * @runInSeparateProcess
     */
    public function testInitPostLangSet()
    {
        $this->setConstants();

        $_POST['lang'] = 'en';
        $_COOKIE['lang'] = 'en';
        Config::set('I18N', array('locales' => array('ru' => 'ru-ru', 'en' => 'en_US'), 'bidi' => 'bidivalue', 'default' => 'ru'));

        set_exit_overload(function() { return FALSE; });

        I18N::init();
        $this->assertAttributeEquals('en_US', 'locale', 'I18N');
        unset_exit_overload();
    }

    /**
     * @runInSeparateProcess
     */
    public function testInitSetDefaultLangNotInLocales()
    {
        $this->setExpectedException('PHPUnit_Framework_Error');
        $this->setConstants();

        Config::set('I18N', array('locales' => array('rus' => 'ru_RU'), 'default' => 'ru'));
        I18N::init();
        $this->assertAttributeEquals('ru_RU', 'locale', 'I18N');
    }

    /**
     * @runInSeparateProcess
     */
    public function testInitServerLangConfigured()
    {
        $this->setConstants();
        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'ru';

        Config::set('I18N', array('locales' => array('ru_ru' => 'ru_RU', 'ru' => 'ru-ru', 'us' => 'en-us')));
        I18N::init();
        $this->assertAttributeEquals('ru-ru', 'locale', 'I18N');
    }

    /**
     * @runInSeparateProcess
     */
    public function testInitServerLangConfiguredWithWeights()
    {
        $this->setConstants();
        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3';

        Config::set('I18N', array('locales' => array('en_US' => 'en-us')));
        I18N::init();
        $this->assertAttributeEquals('en-us', 'locale', 'I18N');
    }

    /**
     * @runInSeparateProcess
     */
    public function testInitServerLangConfiguredWithWeightsNoLocale()
    {
        $this->setConstants();
        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3';

        Config::set('I18N', array('locales' => array('en' => 'en_US')));
        I18N::init();
        $this->assertAttributeEquals('en_US', 'locale', 'I18N');
    }

    /**
     * @runInSeparateProcess
     */
    public function testGetLang()
    {
        $this->setConstants();
        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3';

        Config::set('I18N', array('locales' => array('en' => 'en_US'), 'default' => 'ru'));
        I18N::init();
        $this->assertSame('en', I18N::getLang());
        $this->assertSame('ru', I18N::getDefaultLang());
    }

    /**
     * @runInSeparateProcess
     */
    public function testLangs()
    {
        $this->setConstants();
        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3';

        Config::set('I18N', array('locales' => array('ru' => 'ru-ru'), 'default' => 'ru'));
        I18N::init();
        I18N::setLangs(array('en' => 'en-us', 'fr' => 'fr-fr'));
        $this->assertSame(array('en' => 'en-us', 'fr' => 'fr-fr'), I18N::getLangs());
    }

    /**
     * @runInSeparateProcess
     */
    public function testLangName()
    {
        $this->setConstants();
        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3';

        Config::set('I18N', array('locales' => array('ru' => 'ru-ru'), 'default' => 'ru'));
        I18N::init();
        I18N::setLangs(array('ru' => 'ru_ru', 'en' => 'en-us', 'fr' => 'fr-fr'));
        $this->assertSame('ru_ru', I18N::getLangName());
        $this->assertFalse(I18N::getLangName('br'));
    }

    private function setConstants()
    {
        if (!defined('PATH')) {
            define('PATH', '/some/path/');
        }
        if (!defined('APP')) {
            define('APP', '/some/app/');
        }
    }
}