<?php
/**
 * This file contains the PMO_MyRequest tests.
 *
 * This file is part of the PhpMyObject project,
 * an Object-Relational Mapping (ORM) system.
 * 
 * For questions, help, comments, discussion, etc., please join our
 * forum at {@link http://www.developpez.net/forums/forumdisplay.php?f=770} 
 * or our mailing list at {@link http://groups.google.com/group/pmo-dev}.
 *
 * PhpMyObject is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see {@link http://www.gnu.org/licenses/}.
 *
 * @package			PhpMyObject
 * @subpackage		PMO_Tests
 * @author			Louis Lapointe <laplix@gmail.com>
 * @link				http://pmo.developpez.com/
 * @since			PhpMyObject v0.15
 * @version			$Revision$
 * @copyright		Copyright (C) 2008 Louis Lapointe
 * @license			GPLv3 {@link http://www.gnu.org/licenses/gpl}
 * @filesource
 *
 */ 

/**
 * setup this test case if called individually
 */
if (!defined('PMO_TEST_SUITE')) {
	require_once(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'config.php');
	require_once(SIMPLETEST.DS.'autorun.php');
	require_once(PMO_TESTS . DS . 'simpletest' . DS . 'PMO_HTMLReporter.php');
}


/**
 * requires the PMO_MyController which includes everything needed
 */
require_once(PMO_CORE . DS . 'PMO_MyController.php');

/**
 * tests the PMO_MyRequest class
 */
class PMO_MyRequest_Test extends UnitTestCase
{
	public function __construct() {
		parent::UnitTestCase();
	}

	function test_simple_request() {
		$r = new PMO_MyRequest;

 		$sql = 'SELECT * FROM film';
		$r->from('film');
		$this->assertEqual($sql, $r->toString());
	}

	function test_reset_request() {
		$r = new PMO_MyRequest;

 		$sql = 'SELECT * FROM film';
		$r->from('film');
		$this->assertEqual($sql, $r->toString());

		$r->reset();
		$sql = 'SELECT * FROM actor';
		$r->from('actor');
		$this->assertEqual($sql, $r->toString());
	}

	function test_field() {
		$r = new PMO_MyRequest;

		$sql = 'SELECT * FROM actor';
		$r->field('*')->from('actor');
		$this->assertEqual($sql, $r->toString());

		$sql = 'SELECT actor_id,first_name,last_name FROM actor';

		$r->reset();
		$r->field('actor_id', 'first_name', 'last_name')->from('actor');
		$this->assertEqual($sql, $r->toString());
		
		$r->reset();
		$r->field('actor_id,first_name,last_name')->from('actor');
		$this->assertEqual($sql, $r->toString());

		$r->reset();
		$r->field('actor_id')
			->field('first_name')
			->field('last_name')
			->from('actor');
		$this->assertEqual($sql, $r->toString());

		$r->field('actor_id');
		$this->assertEqual($sql, $r->toString());

		$r->reset();
		$r->field('actor_id')
			->field('last_name')
			->field('first_name')
			->from('actor');
		$this->assertNotEqual($sql, $r->toString());
	}

	function test_from() {
		$r = new PMO_MyRequest;

		try {
			$r->toString();
			$this->fail('request needs a from clause. This should have thrown an exception.');
		}
		catch(Exception $e) {
			$this->assertEqual('Error: FROM clause is empty',$e->getMessage());
		}

		$sql = 'SELECT * FROM actor';
		$r->from('actor');
		$this->assertEqual($sql, $r->toString());

		// no duplicate
		$r->from('actor');
		$this->assertEqual($sql, $r->toString());

		$sql .= ',film,film_actor';
		$r->from('film', 'film_actor');
		$this->assertEqual($sql, $r->toString());

		$r->reset();
		$r->from('actor')->from('film_actor','film');
		$this->assertNotEqual($sql, $r->toString());

	}

	function test_where() {
		$r = new PMO_MyRequest;

		$sql = 'SELECT * FROM actor,film_actor,film';
		$sql .= ' WHERE film_actor.actor_id = actor.actor_id';
	   $sql .= ' AND film.film_id = film_actor.film_id';

		$r->from('actor', 'film_actor', 'film')
		  ->where('film_actor.actor_id = actor.actor_id')
		  ->where('film.film_id = film_actor.film_id');
		$this->assertEqual($sql, $r->toString());

		$r->reset();
		$r->from('actor', 'film_actor', 'film')
			->where('film_actor.actor_id = actor.actor_id',
			  			'film.film_id = film_actor.film_id');
		$this->assertEqual($sql, $r->toString());

		$sql = 'SELECT * FROM actor';
		$sql.= ' WHERE actor.first_name = "CAMERON"';
		$sql.= ' OR actor.first_name = "CATE"';

		$r->reset();
		$r->from('actor')
			->where('actor.first_name = "CAMERON" OR actor.first_name = "CATE"');
		$this->assertEqual($sql, $r->toString());
	}

	function test_groupby() {
		$r = new PMO_MyRequest;

		$sql = 'SELECT first_name,last_name,count(*) FROM actor';
		$sql.= ' WHERE condition = valeur';
		$sql.= ' GROUP BY first_name,last_name';

		$r->field('first_name','last_name', 'count(*)')
			->from('actor')
			->where('condition = valeur')
			->groupby('first_name','last_name');
		$this->assertEqual($sql, $r->toString());

		$r->reset();
		$r->field('first_name','last_name', 'count(*)')
			->from('actor')
			->where('condition = valeur')
			->groupby('first_name');
		$this->assertNotEqual($sql, $r->toString());

		$r->groupby('last_name');
		$this->assertEqual($sql, $r->toString());
	}

	function test_having() {
		$r = new PMO_MyRequest;

		$sql = 'SELECT first_name,last_name,count(*) FROM actor';
		$sql.= ' WHERE conditions';
		$sql.=' HAVING count(*) > 1';

		$r->field('first_name', 'last_name', 'count(*)')
			->from('actor')
			->where('conditions')
			->having('count(*) > 1');
		$this->assertEqual($sql, $r->toString());

		$sql .= ' AND first_name = "CAMERON"';
		$r->having('first_name = "CAMERON"');
		$this->assertEqual($sql, $r->toString());

	}

	function test_order() {
		$r = new PMO_MyRequest;

		$sql = 'SELECT first_name,last_name FROM actor';
		$sql.= ' ORDER BY last_name';

		$r->field('first_name','last_name')
			->from('actor')
			->order('last_name');
		$this->assertEqual($sql, $r->toString());

		$sql.= ',first_name';
		$r->order('first_name');
		$this->assertEqual($sql, $r->toString());

		$r->reset();
		$r->field('first_name','last_name')
			->from('actor')
			->order('last_name','first_name');
		$this->assertEqual($sql, $r->toString());
	}

	function test_limit() {
		$r = new PMO_MyRequest;

		$sql = 'SELECT * FROM actor LIMIT 5';

		$r->from('actor')->limit('5');
		$this->assertEqual($sql, $r->toString());

		// no reset
		$sql = 'SELECT * FROM actor LIMIT 7';
		$r->from('actor')->limit(7);
		$this->assertEqual($sql, $r->toString());
	}

	function test_limit_offset() {
		$r = new PMO_MyRequest;

		$sql = 'SELECT * FROM actor LIMIT 5';

		$r->from('actor')->limit('5');
		$this->assertEqual($sql, $r->toString());

		// no reset
		$sql = 'SELECT * FROM actor LIMIT 5 OFFSET 6';
		$r->from('actor')->limit(5)->offset(6);
		$this->assertEqual($sql, $r->toString());

		$sql = 'SELECT * FROM actor LIMIT 10 OFFSET 11';
		$r->offset('11')->limit('10');
		$this->assertEqual($sql, $r->toString());
	}
}


// run the tests if called individually
if (!defined('PMO_TEST_SUITE')) {
	$level = '';
	if (isset($_COOKIE['testLevel'])) {
		$level = $_COOKIE['testLevel'];
	}
	elseif (isset($_GET['level'])) {
		$level = $_GET['level'];
		setcookie('testLevel', $level, time()+60*60*24*30);
	}

	$test = new TestSuite('PMO_MyRequest Tests');
	$test->add(new PMO_MyRequest_Test);
	$test->run(new PMO_HTMLReporter($level));
}

