<?php

/**
 * This file is part of the Propel package.
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @license    MIT License
 */

require_once 'tools/helpers/bookstore/BookstoreEmptyTestBase.php';

/**
 * Test class for PropelOnDemandFormatter.
 *
 * @author     Francois Zaninotto
 * @version    $Id: PropelOnDemandFormatterTest.php 1374 2009-12-26 23:21:37Z francois $
 * @package    runtime.formatter
 */
class PropelOnDemandFormatterTest extends BookstoreEmptyTestBase
{

	public function testFormatNoCriteria()
	{
		$con = Propel::getConnection(BookPeer::DATABASE_NAME);

		$stmt = $con->query('SELECT * FROM book');
		$formatter = new PropelOnDemandFormatter();
		try {
			$books = $formatter->format($stmt);
			$this->fail('PropelOnDemandFormatter::format() trows an exception when called with no valid criteria');
		} catch (PropelException $e) {
			$this->assertTrue(true,'PropelOnDemandFormatter::format() trows an exception when called with no valid criteria');
		}
	}
	
	public function testFormatManyResults()
	{
		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
		BookstoreDataPopulator::populate($con);

		$stmt = $con->query('SELECT * FROM book');
		$formatter = new PropelOnDemandFormatter();
		$formatter->init(new ModelCriteria('bookstore', 'Book'));
		$books = $formatter->format($stmt);
		
		$this->assertTrue($books instanceof PropelOnDemandCollection, 'PropelOnDemandFormatter::format() returns a PropelOnDemandCollection');
		$this->assertEquals(4, count($books), 'PropelOnDemandFormatter::format() returns a collection that counts as many rows as the results in the query');
		foreach ($books as $book) {
			$this->assertTrue($book instanceof Book, 'PropelOnDemandFormatter::format() returns an traversable collection of Model objects');
		}
	}

	/**
	 * @expectedException PropelException
	 */
	public function testFormatManyResultsIteratedTwice()
	{
		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
		BookstoreDataPopulator::populate($con);

		$stmt = $con->query('SELECT * FROM book');
		$formatter = new PropelOnDemandFormatter();
		$formatter->init(new ModelCriteria('bookstore', 'Book'));
		$books = $formatter->format($stmt);
		
		foreach ($books as $book) {
			// do nothing
		}
		foreach ($books as $book) {
			// this should throw a PropelException since we're iterating a second time over a stream
		}
	}

	public function testFormatALotOfResults()
	{
		$nbBooks = 50;
		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
		Propel::disableInstancePooling();
		$book = new Book();
		for ($i=0; $i < $nbBooks; $i++) { 
			$book->clear();
			$book->setTitle('BookTest' . $i);
			$book->save($con);
		}

		$stmt = $con->query('SELECT * FROM book');
		$formatter = new PropelOnDemandFormatter();
		$formatter->init(new ModelCriteria('bookstore', 'Book'));
		$books = $formatter->format($stmt);
		
		$this->assertTrue($books instanceof PropelOnDemandCollection, 'PropelOnDemandFormatter::format() returns a PropelOnDemandCollection');
		$this->assertEquals($nbBooks, count($books), 'PropelOnDemandFormatter::format() returns a collection that counts as many rows as the results in the query');
		$i = 0;
		foreach ($books as $book) {
			$this->assertTrue($book instanceof Book, 'PropelOnDemandFormatter::format() returns a collection of Model objects');
			$this->assertEquals('BookTest' . $i, $book->getTitle(), 'PropelOnDemandFormatter::format() returns the model objects matching the query');
			$i++;
		}
		Propel::enableInstancePooling();
	}


	public function testFormatOneResult()
	{
		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
		BookstoreDataPopulator::populate($con);
		
		$stmt = $con->query('SELECT * FROM book WHERE book.TITLE = "Quicksilver"');
		$formatter = new PropelOnDemandFormatter();
		$formatter->init(new ModelCriteria('bookstore', 'Book'));
		$books = $formatter->format($stmt);
		
		$this->assertTrue($books instanceof PropelOnDemandCollection, 'PropelOnDemandFormatter::format() returns a PropelOnDemandCollection');
		$this->assertEquals(1, count($books), 'PropelOnDemandFormatter::format() returns a collection that counts as many rows as the results in the query');
		foreach ($books as $book) {
			$this->assertTrue($book instanceof Book, 'PropelOnDemandFormatter::format() returns a collection of Model objects');
			$this->assertEquals('Quicksilver', $book->getTitle(), 'PropelOnDemandFormatter::format() returns the model objects matching the query');
		}
	}

	public function testFormatNoResult()
	{
		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
				
		$stmt = $con->query('SELECT * FROM book WHERE book.TITLE = "foo"');
		$formatter = new PropelOnDemandFormatter();
		$formatter->init(new ModelCriteria('bookstore', 'Book'));
		$books = $formatter->format($stmt);
		
		$this->assertTrue($books instanceof PropelOnDemandCollection, 'PropelOnDemandFormatter::format() returns a PropelCollection');
		$this->assertEquals(0, count($books), 'PropelOnDemandFormatter::format() returns an empty collection when no record match the query');
		foreach ($books as $book) {
			$this->fail('PropelOnDemandFormatter returns an empty iterator when no record match the query');
		}
	}
	
	public function testFormatOneManyResults()
	{
		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
		BookstoreDataPopulator::populate($con);

		$stmt = $con->query('SELECT * FROM book');
		$formatter = new PropelOnDemandFormatter();
		$formatter->init(new ModelCriteria('bookstore', 'Book'));
		$book = $formatter->formatOne($stmt);
		
		$this->assertTrue($book instanceof Book, 'PropelOnDemandFormatter::formatOne() returns a model object');
	}
	
}
