<?php

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

require_once 'vfsStream/vfsStream.php';
require_once dirname(__FILE__) . '/../../util/AutoloadBuilder.php';

/**
 * @TODO: AutoloadBuilder - fix writing to file: construct array first, write to file next - atomic operation
 * @TODO: vfsStream doesn't work with SPLFIleObject->getRealPath - $file->getPath .'/'. $file->getFIleName instead
 */
class AutoloadBuilderTestVFS extends PHPUnit_Framework_TestCase
{

    private static $inc_dirs = array();
    private static $file;
    private $root;
    private $array = array();

    /**
     * @TODO: Load->buildAutoload() - uses two paths - PATH . '/' . APP . '/src' and PATH . '/lib' those are not checked. Can couse error.
     */
    public function setUp()
    {
        if (!defined('PATH')) {
            define('PATH', realpath(dirname(__FILE__) . '/../../../..'));
        }

        if (!defined('APP')) {
            define('APP', 'lib/core/tests/face');
        }

        vfsStreamWrapper::register();
        $this->root = vfsStream::create(
                        array(
                            'cache' => array(
                                'face' => array()
                            ),
                            'face' => array(
                                'src' => array(
                                    'Registry.php' => '   class Registry'
                                )
                            ),
                            'lib' => array(
                                'Registry.php' => '   class Registry',
                                'Load.php' => 'class Load extends Registry',
                                'devel.config' => ' development config file'
                            )
                        )
        );
        vfsStreamWrapper::setRoot($this->root);
    }

    public function testVFS()
    {
        $builder = new AutoloadBuilder(vfsStream::url('root/cache/face/autoload.php'), array(vfsStream::url('root/lib'), vfsStream::url('root/face/src')));
        $this->assertTrue($this->root->hasChild('lib'));
        $this->assertFalse($this->root->hasChild('nochild'));
        $this->assertFalse($this->root->hasChild('cache/face/autoload.php'));
        $handle = fopen(vfsStream::url('root/cache/face/autoload.php'), 'w');
        fwrite($handle, 'new string');
        fclose($handle);
        $this->assertTrue($this->root->hasChild('cache/face/autoload.php'));
        $this->assertSame('new string', $this->root->getChild('cache/face/autoload.php')->getContent());
    }

    public function testBuild()
    {
        $this->markTestSkipped(
                'AutoloadBuilder uses $file->getRealPath method, that doesn`t work properly with vfsStream.'
        );
        $builder = new AutoloadBuilder(vfsStream::url('root/cache/face/autoload.php'), array(vfsStream::url('root/lib'), vfsStream::url('root/face/src')));
        $builder->build();
        $this->assertTrue($this->root->hasChild('cache/face/autoload.php'));
        $this->assertFileExists(vfsStream::url('root/cache/face/autoload.php'));
    }

    public function testAutoloadArray()
    {
        $this->markTestSkipped(
                'AutoloadBuilder uses $file->getRealPath method, that doesn`t work properly with vfsStream.'
        );
        $this->assertFileNotExists(vfsStream::url('root/cache/face/autoload.php'));
        $builder = new AutoloadBuilder(vfsStream::url('root/cache/face/autoload.php'), array(vfsStream::url('root/lib'), vfsStream::url('root/face/src')));
        $builder->build();
        $this->assertFileExists(vfsStream::url('root/cache/face/autoload.php'));
        $this->assertEmpty($this->array);
        $this->array = require vfsStream::url('root/cache/face/autoload.php');
        $this->assertInternalType('array', $this->array);
        $this->assertArrayHasKey('Load', $this->array);
        $this->assertArrayNotHasKey('Key', $this->array);
        $this->assertSame(2, count($this->array));
    }

    public function testAutoloadHasNoAccess()
    {
        $this->markTestSkipped(
                'AutoloadBuilder uses $file->getRealPath method, that doesn`t work properly with vfsStream.'
        );
        $this->assertFileNotExists(vfsStream::url('root/cache/face/autoload.php'));
        $autoloadFIle = new vfsStreamFile('cache/face/autoload.php', 0400);
        $this->root->addChild($autoloadFIle);
        $builder = new AutoloadBuilder(vfsStream::url('root/cache/face/autoload.php'), array(vfsStream::url('root/lib'), vfsStream::url('root/face/src')));
        $builder->build();
        $this->assertFileExists(vfsStream::url('root/cache/face/autoload.php'));
        $this->assertEmpty($this->root->getChild('cache/face/autoload.php')->getContent());
        $this->array = require vfsStream::url('root/cache/face/autoload.php');
        $this->assertInternalType('integer', $this->array);

        $autoloadFIle->chmod(0777);
        $builder = new AutoloadBuilder(vfsStream::url('root/cache/face/autoload.php'), array(vfsStream::url('root/lib'), vfsStream::url('root/face/src')));
        $builder->build();
        $this->assertFileExists(vfsStream::url('root/cache/face/autoload.php'));
        $this->assertNotEmpty($this->root->getChild('cache/face/autoload.php')->getContent());
        $this->array = require vfsStream::url('root/cache/face/autoload.php');
        $this->assertInternalType('array', $this->array);
        $this->assertNotEmpty($this->array);
    }

}