<?php

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

require_once dirname(__FILE__) . '/../../model/Db.php';
require_once dirname(__FILE__) . '/../../model/DbDriver.php';
require_once dirname(__FILE__) . '/../../model/DbStatement.php';
require_once dirname(__FILE__) . '/../../exception/GeneralException.php';

class DbStatementTest extends PHPUnit_Framework_TestCase
{
    private $driver;

    private $sql;

    private $stmt;

    private $testData = array(
        array('one' => 11, 'two' => 12),
        array('one' => 21, 'two' => 22),
        array('one' => 31, 'two' => 32),
    );

    public function setUp()
    {
        if (!isset($this->stmt)) {
            $this->driver = $this->getMockBuilder('DbDriverMock')
                    ->disableOriginalConstructor()
                    ->setMethods(array('quote'))
                    ->getMock();
            $this->sql = 'SELECT * :place FROM :place AND :new';
            $this->stmt = $this->getMockForAbstractClass('DbStatement', array($this->driver, $this->sql));
        }
    }

    public function testConstruct()
    {
        $this->assertAttributeEquals($this->driver, 'driver', $this->stmt);
        $this->assertAttributeEquals($this->sql, 'request', $this->stmt);
    }

    public function testFetch()
    {
        $this->stmt
                ->expects($this->any())
                ->method('fetch')
                ->with($this->anything())
                ->will($this->returnCallback(array($this, 'dbStatementFetch')));

        $this->assertSame(11, $this->stmt->fetchField('one'));
        $this->assertFalse($this->stmt->fetchField('zero'));

        reset($this->testData);
        $this->assertSame(array(11, 21, 31), $this->stmt->fetchColumn('one'));

        reset($this->testData);
        $result = $this->stmt->fetchAll();
        $this->assertSame(11, $result[0]->one);
        $this->assertSame(32, $result[2]->two);

//        reset($this->testData);
//        $result = $this->stmt->fetchPairs();
//        $this->assertEquals(31, $result['one']);
    }

    public function dbStatementFetch($style)
    {
        $result = null;
        switch ($style) {
            case Db::FETCH_OBJ:
                $data = each($this->testData);
                if ($data !== false) {
                    $result = new ArrayObject($data['value'], ArrayObject::ARRAY_AS_PROPS);
                } else {
                    $result = false;
                }
                break;
            case Db::FETCH_ASSOC:
                $data = each($this->testData);
                $result = $data['value'];
                break;
            case Db::FETCH_NUM:
                $data = each($this->testData);
                if ($data !== false) {
                    $data = $data['value'];
                    $result[0] = key($data);
                    $result[1] = current($data);
                } else {
                    $result = false;
                }
        }
        return $result;
    }
}