PageRenderTime 50ms CodeModel.GetById 12ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/forum/library/propel/tmp/test/testsuite/generator/builder/om/QueryBuilderTest.php

https://github.com/albrzykowski/zforum
PHP | 912 lines | 730 code | 150 blank | 32 comment | 3 complexity | 720c3af2d01e1a66493953b0b5a2c79b MD5 | raw file
  1<?php
  2
  3/**
  4 * This file is part of the Propel package.
  5 * For the full copyright and license information, please view the LICENSE
  6 * file that was distributed with this source code.
  7 *
  8 * @license    MIT License
  9 */
 10
 11require_once 'tools/helpers/bookstore/BookstoreTestBase.php';
 12require_once 'tools/helpers/bookstore/BookstoreDataPopulator.php';
 13
 14/**
 15 * Test class for QueryBuilder.
 16 *
 17 * @author     Franรงois Zaninotto
 18 * @version    $Id: QueryBuilderTest.php 1347 2009-12-03 21:06:36Z francois $
 19 * @package    generator.builder.om
 20 */
 21class QueryBuilderTest extends BookstoreTestBase 
 22{ 
 23  
 24	public function testExtends()
 25	{
 26		$q = new BookQuery();
 27		$this->assertTrue($q instanceof ModelCriteria, 'Model query extends ModelCriteria');
 28	}
 29	
 30	public function testConstructor()
 31	{
 32		$query = new BookQuery();
 33		$this->assertEquals($query->getDbName(), 'bookstore', 'Constructor sets dabatase name');
 34		$this->assertEquals($query->getModelName(), 'Book', 'Constructor sets model name');
 35	}
 36	
 37	public function testCreate()
 38	{
 39		$query = BookQuery::create();
 40		$this->assertTrue($query instanceof BookQuery, 'create() returns an object of its class');
 41		$this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
 42		$this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
 43		$query = BookQuery::create('foo');
 44		$this->assertTrue($query instanceof BookQuery, 'create() returns an object of its class');
 45		$this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
 46		$this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
 47		$this->assertEquals($query->getModelAlias(), 'foo', 'create() can set the model alias');
 48	}
 49	
 50	public function testCreateCustom()
 51	{
 52		// see the myBookQuery class definition at the end of this file
 53		$query = myCustomBookQuery::create();
 54		$this->assertTrue($query instanceof myCustomBookQuery, 'create() returns an object of its class');
 55		$this->assertTrue($query instanceof BookQuery, 'create() returns an object of its class');
 56		$this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
 57		$this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
 58		$query = myCustomBookQuery::create('foo');
 59		$this->assertTrue($query instanceof myCustomBookQuery, 'create() returns an object of its class');
 60		$this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
 61		$this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
 62		$this->assertEquals($query->getModelAlias(), 'foo', 'create() can set the model alias');
 63	}
 64	
 65	public function testBasePreSelect()
 66	{
 67		$method = new ReflectionMethod('Table2Query', 'basePreSelect');
 68		$this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePreSelect() by default');
 69		
 70		$method = new ReflectionMethod('Table3Query', 'basePreSelect');
 71		$this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePreSelect() when a behavior is registered');
 72	}
 73
 74	public function testBasePreDelete()
 75	{
 76		$method = new ReflectionMethod('Table2Query', 'basePreDelete');
 77		$this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePreDelete() by default');
 78		
 79		$method = new ReflectionMethod('Table3Query', 'basePreDelete');
 80		$this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePreDelete() when a behavior is registered');
 81	}
 82
 83	public function testBasePostDelete()
 84	{
 85		$method = new ReflectionMethod('Table2Query', 'basePostDelete');
 86		$this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePostDelete() by default');
 87
 88		$method = new ReflectionMethod('Table3Query', 'basePostDelete');
 89		$this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePostDelete() when a behavior is registered');
 90	}
 91	
 92	public function testBasePreUpdate()
 93	{
 94		$method = new ReflectionMethod('Table2Query', 'basePreUpdate');
 95		$this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePreUpdate() by default');
 96
 97		$method = new ReflectionMethod('Table3Query', 'basePreUpdate');
 98		$this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePreUpdate() when a behavior is registered');
 99	}
100
101	public function testBasePostUpdate()
102	{
103		$method = new ReflectionMethod('Table2Query', 'basePostUpdate');
104		$this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePostUpdate() by default');
105
106		$method = new ReflectionMethod('Table3Query', 'basePostUpdate');
107		$this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePostUpdate() when a behavior is registered');
108	}
109	
110	public function testQuery()
111	{
112		BookstoreDataPopulator::depopulate();
113		BookstoreDataPopulator::populate();
114		
115		$q = new BookQuery();
116		$book = $q
117			->setModelAlias('b')
118			->where('b.Title like ?', 'Don%')
119			->orderBy('b.ISBN', 'desc')
120			->findOne();
121		$this->assertTrue($book instanceof Book);
122		$this->assertEquals('Don Juan', $book->getTitle());
123	}
124	
125	public function testFindPk()
126	{
127		$method = new ReflectionMethod('Table4Query', 'findPk');
128		$this->assertEquals('BaseTable4Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides findPk()');
129	}
130	
131	public function testFindPkSimpleKey()
132	{
133		BookstoreDataPopulator::depopulate();
134		BookstoreDataPopulator::populate();
135		
136		BookPeer::clearInstancePool();
137		$con = Propel::getConnection('bookstore');
138		
139		// prepare the test data
140		$c = new ModelCriteria('bookstore', 'Book');
141		$c->orderBy('Book.Id', 'desc');
142		$testBook = $c->findOne();
143		$count = $con->getQueryCount();
144
145		BookPeer::clearInstancePool();
146		
147		$q = new BookQuery();
148		$book = $q->findPk($testBook->getId());
149		$this->assertEquals($testBook, $book, 'BaseQuery overrides findPk() to make it faster');
150		$this->assertEquals($count+1, $con->getQueryCount(), 'findPk() issues a database query when instance pool is empty');
151
152		$q = new BookQuery();
153		$book = $q->findPk($testBook->getId());
154		$this->assertEquals($testBook, $book, 'BaseQuery overrides findPk() to make it faster');
155		$this->assertEquals($count+1, $con->getQueryCount(), 'findPk() does not issue a database query when instance is in pool');
156	}
157	
158	public function testFindPkCompositeKey()
159	{
160		BookstoreDataPopulator::depopulate();
161		BookstoreDataPopulator::populate();
162		
163		// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
164		$c = new ModelCriteria('bookstore', 'Book');
165		$books = $c->find();
166		foreach ($books as $book) {
167			$book->save();
168		}
169
170		BookPeer::clearInstancePool();
171		
172		// retrieve the test data
173		$c = new ModelCriteria('bookstore', 'BookListRel');
174		$bookListRelTest = $c->findOne();
175		$pk = $bookListRelTest->getPrimaryKey();
176		
177		$q = new BookListRelQuery();
178		$bookListRel = $q->findPk($pk);
179		$this->assertEquals($bookListRelTest, $bookListRel, 'BaseQuery overrides findPk() for composite primary keysto make it faster');
180	}
181
182	public function testFindPks()
183	{
184		$method = new ReflectionMethod('Table4Query', 'findPks');
185		$this->assertEquals('BaseTable4Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides findPks()');
186	}
187
188	public function testFindPksSimpleKey()
189	{
190		BookstoreDataPopulator::depopulate();
191		BookstoreDataPopulator::populate();
192		
193		BookPeer::clearInstancePool();
194		
195		// prepare the test data
196		$c = new ModelCriteria('bookstore', 'Book');
197		$c->orderBy('Book.Id', 'desc');
198		$testBooks = $c->find();
199		$testBook1 = $testBooks->pop();
200		$testBook2 = $testBooks->pop();
201
202		$q = new BookQuery();
203		$books = $q->findPks(array($testBook1->getId(), $testBook2->getId()));
204		$this->assertEquals(array($testBook1, $testBook2), $books->getData(), 'BaseQuery overrides findPks() to make it faster');
205	}
206	
207	public function testFindPksCompositeKey()
208	{
209		BookstoreDataPopulator::depopulate();
210		BookstoreDataPopulator::populate();
211		
212		// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
213		$c = new ModelCriteria('bookstore', 'Book');
214		$books = $c->find();
215		foreach ($books as $book) {
216			$book->save();
217		}
218
219		BookPeer::clearInstancePool();
220		
221		// retrieve the test data
222		$c = new ModelCriteria('bookstore', 'BookListRel');
223		$bookListRelTest = $c->find();
224		$search = array();
225		foreach ($bookListRelTest as $obj) {
226			$search[]= $obj->getPrimaryKey();
227		}
228		
229		$q = new BookListRelQuery();
230		$objs = $q->findPks($search);
231		$this->assertEquals($bookListRelTest, $objs, 'BaseQuery overrides findPks() for composite primary keys to make it work');
232	}
233	
234	public function testFilterBy()
235	{
236		foreach (BookPeer::getFieldNames(BasePeer::TYPE_PHPNAME) as $colName) {
237			$filterMethod = 'filterBy' . $colName;
238			$this->assertTrue(method_exists('BookQuery', $filterMethod), 'QueryBuilder adds filterByColumn() methods for every column');
239			$q = BookQuery::create()->$filterMethod(1);
240			$this->assertTrue($q instanceof BookQuery, 'filterByColumn() returns the current query instance');
241		}
242	}
243
244	public function testFilterByPrimaryKeySimpleKey()
245	{
246		$q = BookQuery::create()->filterByPrimaryKey(12);
247		$q1 = BookQuery::create()->add(BookPeer::ID, 12, Criteria::EQUAL);
248		$this->assertEquals($q1, $q, 'filterByPrimaryKey() translates to a Criteria::EQUAL in the PK column');
249
250		$q = BookQuery::create()->setModelAlias('b', true)->filterByPrimaryKey(12);
251		$q1 = BookQuery::create()->setModelAlias('b', true)->add('b.ID', 12, Criteria::EQUAL);
252		$this->assertEquals($q1, $q, 'filterByPrimaryKey() uses true table alias if set');
253	}
254
255	public function testFilterByPrimaryKeyCompositeKey()
256	{
257		BookstoreDataPopulator::depopulate();
258		BookstoreDataPopulator::populate();
259		
260		// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
261		$c = new ModelCriteria('bookstore', 'Book');
262		$books = $c->find();
263		foreach ($books as $book) {
264			$book->save();
265		}
266
267		BookPeer::clearInstancePool();
268		
269		// retrieve the test data
270		$c = new ModelCriteria('bookstore', 'BookListRel');
271		$bookListRelTest = $c->findOne();
272		$pk = $bookListRelTest->getPrimaryKey();
273		
274		$q = new BookListRelQuery();
275		$q->filterByPrimaryKey($pk);
276		
277		$q1 = BookListRelQuery::create()
278			->add(BookListRelPeer::BOOK_ID, $pk[0], Criteria::EQUAL)
279			->add(BookListRelPeer::BOOK_CLUB_LIST_ID, $pk[1], Criteria::EQUAL);
280		$this->assertEquals($q1, $q, 'filterByPrimaryKey() translates to a Criteria::EQUAL in the PK columns');
281	}
282		
283	public function testFilterByPrimaryKeysSimpleKey()
284	{
285		$q = BookQuery::create()->filterByPrimaryKeys(array(10, 11, 12));
286		$q1 = BookQuery::create()->add(BookPeer::ID, array(10, 11, 12), Criteria::IN);
287		$this->assertEquals($q1, $q, 'filterByPrimaryKeys() translates to a Criteria::IN on the PK column');
288
289		$q = BookQuery::create()->setModelAlias('b', true)->filterByPrimaryKeys(array(10, 11, 12));
290		$q1 = BookQuery::create()->setModelAlias('b', true)->add('b.ID', array(10, 11, 12), Criteria::IN);
291		$this->assertEquals($q1, $q, 'filterByPrimaryKeys() uses true table alias if set');
292	}
293
294	public function testFilterByPrimaryKeysCompositeKey()
295	{
296		BookstoreDataPopulator::depopulate();
297		BookstoreDataPopulator::populate();
298		
299		// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
300		$c = new ModelCriteria('bookstore', 'Book');
301		$books = $c->find();
302		foreach ($books as $book) {
303			$book->save();
304		}
305
306		BookPeer::clearInstancePool();
307		
308		// retrieve the test data
309		$c = new ModelCriteria('bookstore', 'BookListRel');
310		$bookListRelTest = $c->find();
311		$search = array();
312		foreach ($bookListRelTest as $obj) {
313			$search[]= $obj->getPrimaryKey();
314		}
315		
316		$q = new BookListRelQuery();
317		$q->filterByPrimaryKeys($search);
318		
319		$q1 = BookListRelQuery::create();
320		foreach ($search as $key) {
321			$cton0 = $q1->getNewCriterion(BookListRelPeer::BOOK_ID, $key[0], Criteria::EQUAL);
322			$cton1 = $q1->getNewCriterion(BookListRelPeer::BOOK_CLUB_LIST_ID, $key[1], Criteria::EQUAL);
323			$cton0->addAnd($cton1);
324			$q1->addOr($cton0);
325		}
326		$this->assertEquals($q1, $q, 'filterByPrimaryKeys() translates to a series of Criteria::EQUAL in the PK columns');
327	}
328	
329	public function testFilterByIntegerPk()
330	{
331		$q = BookQuery::create()->filterById(12);
332		$q1 = BookQuery::create()->add(BookPeer::ID, 12, Criteria::EQUAL);
333		$this->assertEquals($q1, $q, 'filterByPkColumn() translates to a Criteria::EQUAL by default');
334
335		$q = BookQuery::create()->filterById(12, Criteria::NOT_EQUAL);
336		$q1 = BookQuery::create()->add(BookPeer::ID, 12, Criteria::NOT_EQUAL);
337		$this->assertEquals($q1, $q, 'filterByPkColumn() accepts an optional comparison operator');
338		
339		$q = BookQuery::create()->setModelAlias('b', true)->filterById(12);
340		$q1 = BookQuery::create()->setModelAlias('b', true)->add('b.ID', 12, Criteria::EQUAL);
341		$this->assertEquals($q1, $q, 'filterByPkColumn() uses true table alias if set');
342
343		$q = BookQuery::create()->filterById(array(10, 11, 12));
344		$q1 = BookQuery::create()->add(BookPeer::ID, array(10, 11, 12), Criteria::IN);
345		$this->assertEquals($q1, $q, 'filterByPkColumn() translates to a Criteria::IN when passed a simple array key');
346
347		$q = BookQuery::create()->filterById(array(10, 11, 12), Criteria::NOT_IN);
348		$q1 = BookQuery::create()->add(BookPeer::ID, array(10, 11, 12), Criteria::NOT_IN);
349		$this->assertEquals($q1, $q, 'filterByPkColumn() accepts a comparison when passed a simple array key');
350	}
351	
352	public function testFilterByNumber()
353	{
354		$q = BookQuery::create()->filterByPrice(12);
355		$q1 = BookQuery::create()->add(BookPeer::PRICE, 12, Criteria::EQUAL);
356		$this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::EQUAL by default');
357
358		$q = BookQuery::create()->filterByPrice(12, Criteria::NOT_EQUAL);
359		$q1 = BookQuery::create()->add(BookPeer::PRICE, 12, Criteria::NOT_EQUAL);
360		$this->assertEquals($q1, $q, 'filterByNumColumn() accepts an optional comparison operator');
361		
362		$q = BookQuery::create()->setModelAlias('b', true)->filterByPrice(12);
363		$q1 = BookQuery::create()->setModelAlias('b', true)->add('b.PRICE', 12, Criteria::EQUAL);
364		$this->assertEquals($q1, $q, 'filterByNumColumn() uses true table alias if set');
365
366		$q = BookQuery::create()->filterByPrice(array(10, 11, 12));
367		$q1 = BookQuery::create()->add(BookPeer::PRICE, array(10, 11, 12), Criteria::IN);
368		$this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::IN when passed a simple array key');
369
370		$q = BookQuery::create()->filterByPrice(array(10, 11, 12), Criteria::NOT_IN);
371		$q1 = BookQuery::create()->add(BookPeer::PRICE, array(10, 11, 12), Criteria::NOT_IN);
372		$this->assertEquals($q1, $q, 'filterByNumColumn() accepts a comparison when passed a simple array key');
373		
374		$q = BookQuery::create()->filterByPrice(array('min' => 10));
375		$q1 = BookQuery::create()->add(BookPeer::PRICE, 10, Criteria::GREATER_EQUAL);
376		$this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::GREATER_EQUAL when passed a \'min\' key');
377
378		$q = BookQuery::create()->filterByPrice(array('max' => 12));
379		$q1 = BookQuery::create()->add(BookPeer::PRICE, 12, Criteria::LESS_EQUAL);
380		$this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::LESS_EQUAL when passed a \'max\' key');
381
382		$q = BookQuery::create()->filterByPrice(array('min' => 10, 'max' => 12));
383		$q1 = BookQuery::create()
384			->add(BookPeer::PRICE, 10, Criteria::GREATER_EQUAL)
385			->addAnd(BookPeer::PRICE, 12, Criteria::LESS_EQUAL);
386		$this->assertEquals($q1, $q, 'filterByNumColumn() translates to a between when passed both a \'min\' and a \'max\' key');
387	}
388
389	public function testFilterByTimestamp()
390	{
391		$q = BookstoreEmployeeAccountQuery::create()->filterByCreated(12);
392		$q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::EQUAL);
393		$this->assertEquals($q1, $q, 'filterByDateColumn() translates to a Criteria::EQUAL by default');
394
395		$q = BookstoreEmployeeAccountQuery::create()->filterByCreated(12, Criteria::NOT_EQUAL);
396		$q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::NOT_EQUAL);
397		$this->assertEquals($q1, $q, 'filterByDateColumn() accepts an optional comparison operator');
398		
399		$q = BookstoreEmployeeAccountQuery::create()->setModelAlias('b', true)->filterByCreated(12);
400		$q1 = BookstoreEmployeeAccountQuery::create()->setModelAlias('b', true)->add('b.CREATED', 12, Criteria::EQUAL);
401		$this->assertEquals($q1, $q, 'filterByDateColumn() uses true table alias if set');
402		
403		$q = BookstoreEmployeeAccountQuery::create()->filterByCreated(array('min' => 10));
404		$q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 10, Criteria::GREATER_EQUAL);
405		$this->assertEquals($q1, $q, 'filterByDateColumn() translates to a Criteria::GREATER_EQUAL when passed a \'min\' key');
406
407		$q = BookstoreEmployeeAccountQuery::create()->filterByCreated(array('max' => 12));
408		$q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::LESS_EQUAL);
409		$this->assertEquals($q1, $q, 'filterByDateColumn() translates to a Criteria::LESS_EQUAL when passed a \'max\' key');
410
411		$q = BookstoreEmployeeAccountQuery::create()->filterByCreated(array('min' => 10, 'max' => 12));
412		$q1 = BookstoreEmployeeAccountQuery::create()
413			->add(BookstoreEmployeeAccountPeer::CREATED, 10, Criteria::GREATER_EQUAL)
414			->addAnd(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::LESS_EQUAL);
415		$this->assertEquals($q1, $q, 'filterByDateColumn() translates to a between when passed both a \'min\' and a \'max\' key');
416	}
417
418	public function testFilterByString()
419	{
420		$q = BookQuery::create()->filterByTitle('foo');
421		$q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo', Criteria::EQUAL);
422		$this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::EQUAL by default');
423		
424		$q = BookQuery::create()->filterByTitle('foo', Criteria::NOT_EQUAL);
425		$q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo', Criteria::NOT_EQUAL);
426		$this->assertEquals($q1, $q, 'filterByStringColumn() accepts an optional comparison operator');
427		
428		$q = BookQuery::create()->setModelAlias('b', true)->filterByTitle('foo');
429		$q1 = BookQuery::create()->setModelAlias('b', true)->add('b.TITLE', 'foo', Criteria::EQUAL);
430		$this->assertEquals($q1, $q, 'filterByStringColumn() uses true table alias if set');
431		
432		$q = BookQuery::create()->filterByTitle(array('foo', 'bar'));
433		$q1 = BookQuery::create()->add(BookPeer::TITLE, array('foo', 'bar'), Criteria::IN);
434		$this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::IN when passed an array');
435
436		$q = BookQuery::create()->filterByTitle(array('foo', 'bar'), Criteria::NOT_IN);
437		$q1 = BookQuery::create()->add(BookPeer::TITLE, array('foo', 'bar'), Criteria::NOT_IN);
438		$this->assertEquals($q1, $q, 'filterByStringColumn() accepts a comparison when passed an array');
439		
440		$q = BookQuery::create()->filterByTitle('foo%');
441		$q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo%', Criteria::LIKE);
442		$this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::LIKE when passed a string with a % wildcard');
443
444		$q = BookQuery::create()->filterByTitle('foo%', Criteria::NOT_LIKE);
445		$q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo%', Criteria::NOT_LIKE);
446		$this->assertEquals($q1, $q, 'filterByStringColumn() accepts a comparison when passed a string with a % wildcard');
447
448		$q = BookQuery::create()->filterByTitle('foo%', Criteria::EQUAL);
449		$q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo%', Criteria::EQUAL);
450		$this->assertEquals($q1, $q, 'filterByStringColumn() accepts a comparison when passed a string with a % wildcard');
451
452		$q = BookQuery::create()->filterByTitle('*foo');
453		$q1 = BookQuery::create()->add(BookPeer::TITLE, '%foo', Criteria::LIKE);
454		$this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::LIKE when passed a string with a * wildcard, and turns * into %');
455
456		$q = BookQuery::create()->filterByTitle('*f%o*o%');
457		$q1 = BookQuery::create()->add(BookPeer::TITLE, '%f%o%o%', Criteria::LIKE);
458		$this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::LIKE when passed a string with mixed wildcards, and turns *s into %s');
459	}
460
461	public function testFilterByBoolean()
462	{
463		$q = ReviewQuery::create()->filterByRecommended(true);
464		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
465		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a Criteria::EQUAL by default');
466
467		$q = ReviewQuery::create()->filterByRecommended(true, Criteria::NOT_EQUAL);
468		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::NOT_EQUAL);
469		$this->assertEquals($q1, $q, 'filterByBooleanColumn() accepts an optional comparison operator');
470
471		$q = ReviewQuery::create()->filterByRecommended(false);
472		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
473		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a Criteria::EQUAL by default');
474		
475		$q = ReviewQuery::create()->setModelAlias('b', true)->filterByRecommended(true);
476		$q1 = ReviewQuery::create()->setModelAlias('b', true)->add('b.RECOMMENDED', true, Criteria::EQUAL);
477		$this->assertEquals($q1, $q, 'filterByBooleanColumn() uses true table alias if set');
478		
479		$q = ReviewQuery::create()->filterByRecommended('true');
480		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
481		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = true when passed a true string');
482
483		$q = ReviewQuery::create()->filterByRecommended('yes');
484		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
485		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = true when passed a true string');
486
487		$q = ReviewQuery::create()->filterByRecommended('1');
488		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
489		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = true when passed a true string');
490		
491		$q = ReviewQuery::create()->filterByRecommended('false');
492		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
493		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = false when passed a false string');
494
495		$q = ReviewQuery::create()->filterByRecommended('no');
496		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
497		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = false when passed a false string');
498
499		$q = ReviewQuery::create()->filterByRecommended('0');
500		$q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
501		$this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = false when passed a false string');
502	}
503		
504	public function testFilterByFk()
505	{
506		$this->assertTrue(method_exists('BookQuery', 'filterByAuthor'), 'QueryBuilder adds filterByFk() methods');
507		$this->assertTrue(method_exists('BookQuery', 'filterByPublisher'), 'QueryBuilder adds filterByFk() methods for all fkeys');
508		
509		$this->assertTrue(method_exists('EssayQuery', 'filterByAuthorRelatedByFirstAuthor'), 'QueryBuilder adds filterByFk() methods for several fkeys on the same table');
510		$this->assertTrue(method_exists('EssayQuery', 'filterByAuthorRelatedBySecondAuthor'), 'QueryBuilder adds filterByFk() methods for several fkeys on the same table');		
511	}
512	
513	public function testFilterByFkSimpleKey()
514	{
515		BookstoreDataPopulator::depopulate();
516		BookstoreDataPopulator::populate();
517		
518		// prepare the test data
519		$testBook = BookQuery::create()
520			->innerJoin('Book.Author') // just in case there are books with no author
521			->findOne();
522		$testAuthor = $testBook->getAuthor();
523		
524		$book = BookQuery::create()
525			->filterByAuthor($testAuthor)
526			->findOne();
527		$this->assertEquals($testBook, $book, 'Generated query handles filterByFk() methods correctly for simple fkeys');
528
529		$q = BookQuery::create()->filterByAuthor($testAuthor);
530		$q1 = BookQuery::create()->add(BookPeer::AUTHOR_ID, $testAuthor->getId(), Criteria::EQUAL);
531		$this->assertEquals($q1, $q, 'filterByFk() translates to a Criteria::EQUAL by default');
532		
533		$q = BookQuery::create()->filterByAuthor($testAuthor, Criteria::NOT_EQUAL);
534		$q1 = BookQuery::create()->add(BookPeer::AUTHOR_ID, $testAuthor->getId(), Criteria::NOT_EQUAL);
535		$this->assertEquals($q1, $q, 'filterByFk() accepts an optional comparison operator');
536	}
537
538	public function testFilterByFkCompositeKey()
539	{
540		BookstoreDataPopulator::depopulate();
541		BookstoreDataPopulator::populate();
542		BookstoreDataPopulator::populateOpinionFavorite();
543		
544		// prepare the test data
545		$testOpinion = BookOpinionQuery::create()
546			->innerJoin('BookOpinion.ReaderFavorite') // just in case there are books with no author
547			->findOne();
548		$testFavorite = $testOpinion->getReaderFavorite();
549
550		$favorite = ReaderFavoriteQuery::create()
551			->filterByBookOpinion($testOpinion)
552			->findOne();
553		$this->assertEquals($testFavorite, $favorite, 'Generated query handles filterByFk() methods correctly for composite fkeys');
554	}
555	
556		public function testFilterByRefFk()
557	{
558		$this->assertTrue(method_exists('BookQuery', 'filterByReview'), 'QueryBuilder adds filterByRefFk() methods');
559		$this->assertTrue(method_exists('BookQuery', 'filterByMedia'), 'QueryBuilder adds filterByRefFk() methods for all fkeys');
560		
561		$this->assertTrue(method_exists('AuthorQuery', 'filterByEssayRelatedByFirstAuthor'), 'QueryBuilder adds filterByRefFk() methods for several fkeys on the same table');
562		$this->assertTrue(method_exists('AuthorQuery', 'filterByEssayRelatedBySecondAuthor'), 'QueryBuilder adds filterByRefFk() methods for several fkeys on the same table');				
563	}
564
565	public function testFilterByRefFkSimpleKey()
566	{
567		BookstoreDataPopulator::depopulate();
568		BookstoreDataPopulator::populate();
569		
570		// prepare the test data
571		$testBook = BookQuery::create()
572			->innerJoin('Book.Author') // just in case there are books with no author
573			->findOne();
574		$testAuthor = $testBook->getAuthor();
575
576		$author = AuthorQuery::create()
577			->filterByBook($testBook)
578			->findOne();
579		$this->assertEquals($testAuthor, $author, 'Generated query handles filterByRefFk() methods correctly for simple fkeys');
580
581		$q = AuthorQuery::create()->filterByBook($testBook);
582		$q1 = AuthorQuery::create()->add(AuthorPeer::ID, $testBook->getAuthorId(), Criteria::EQUAL);
583		$this->assertEquals($q1, $q, 'filterByRefFk() translates to a Criteria::EQUAL by default');
584
585		$q = AuthorQuery::create()->filterByBook($testBook, Criteria::NOT_EQUAL);
586		$q1 = AuthorQuery::create()->add(AuthorPeer::ID, $testBook->getAuthorId(), Criteria::NOT_EQUAL);
587		$this->assertEquals($q1, $q, 'filterByRefFk() accepts an optional comparison operator');
588	}
589	
590	public function testFilterByRefFkCompositeKey()
591	{
592		BookstoreDataPopulator::depopulate();
593		BookstoreDataPopulator::populate();
594		BookstoreDataPopulator::populateOpinionFavorite();
595		
596		// prepare the test data
597		$testOpinion = BookOpinionQuery::create()
598			->innerJoin('BookOpinion.ReaderFavorite') // just in case there are books with no author
599			->findOne();
600		$testFavorite = $testOpinion->getReaderFavorite();
601
602		$opinion = BookOpinionQuery::create()
603			->filterByReaderFavorite($testFavorite)
604			->findOne();
605		$this->assertEquals($testOpinion, $opinion, 'Generated query handles filterByRefFk() methods correctly for composite fkeys');
606	}
607	
608	public function testFilterByCrossFK()
609	{
610		$this->assertTrue(method_exists('BookQuery', 'filterByBookClubList'), 'Generated query handles filterByCrossRefFK() for many-to-many relationships');
611		$this->assertFalse(method_exists('BookQuery', 'filterByBook'), 'Generated query handles filterByCrossRefFK() for many-to-many relationships');
612		BookstoreDataPopulator::depopulate();
613		BookstoreDataPopulator::populate();
614		$blc1 = BookClubListQuery::create()->findOneByGroupLeader('Crazyleggs');
615		$nbBooks = BookQuery::create()
616			->filterByBookClubList($blc1)
617			->count();
618		$this->assertEquals(2, $nbBooks, 'Generated query handles filterByCrossRefFK() methods correctly');
619	}
620	
621	public function testJoinFk()
622	{
623		$q = BookQuery::create()
624			->joinAuthor();
625		$q1 = BookQuery::create()
626			->join('Book.Author', Criteria::LEFT_JOIN);
627		$this->assertTrue($q->equals($q1), 'joinFk() translates to a left join on non-required columns');
628
629		$q = ReviewQuery::create()
630			->joinBook();
631		$q1 = ReviewQuery::create()
632			->join('Review.Book', Criteria::INNER_JOIN);
633		$this->assertTrue($q->equals($q1), 'joinFk() translates to an inner join on required columns');
634
635		$q = BookQuery::create()
636			->joinAuthor('a');
637		$q1 = BookQuery::create()
638			->join('Book.Author a', Criteria::LEFT_JOIN);
639		$this->assertTrue($q->equals($q1), 'joinFk() accepts a relation alias as first parameter');
640
641		$q = BookQuery::create()
642			->joinAuthor('', Criteria::INNER_JOIN);
643		$q1 = BookQuery::create()
644			->join('Book.Author', Criteria::INNER_JOIN);
645		$this->assertTrue($q->equals($q1), 'joinFk() accepts a join type as second parameter');
646
647		$q = EssayQuery::create()
648			->joinAuthorRelatedBySecondAuthor();
649		$q1 = EssayQuery::create()
650			->join('Essay.AuthorRelatedBySecondAuthor', "INNER JOIN");
651		$this->assertTrue($q->equals($q1), 'joinFk() translates to a "INNER JOIN" when this is defined as defaultJoin in the schema');		
652	}
653	
654	public function testJoinFkAlias()
655	{
656		$q = BookQuery::create('b')
657			->joinAuthor('a');
658		$q1 = BookQuery::create('b')
659			->join('b.Author a', Criteria::LEFT_JOIN);
660		$this->assertTrue($q->equals($q1), 'joinFk() works fine with table aliases');
661
662		$q = BookQuery::create()
663			->setModelAlias('b', true)
664			->joinAuthor('a');
665		$q1 = BookQuery::create()
666			->setModelAlias('b', true)
667			->join('b.Author a', Criteria::LEFT_JOIN);
668		$this->assertTrue($q->equals($q1), 'joinFk() works fine with true table aliases');
669	}
670
671	public function testJoinRefFk()
672	{
673		$q = AuthorQuery::create()
674			->joinBook();
675		$q1 = AuthorQuery::create()
676			->join('Author.Book', Criteria::LEFT_JOIN);
677		$this->assertTrue($q->equals($q1), 'joinRefFk() translates to a left join on non-required columns');
678
679		$q = BookQuery::create()
680			->joinreview();
681		$q1 = BookQuery::create()
682			->join('Book.Review', Criteria::INNER_JOIN);
683		$this->assertTrue($q->equals($q1), 'joinRefFk() translates to an inner join on required columns');
684
685		$q = AuthorQuery::create()
686			->joinBook('b');
687		$q1 = AuthorQuery::create()
688			->join('Author.Book b', Criteria::LEFT_JOIN);
689		$this->assertTrue($q->equals($q1), 'joinRefFk() accepts a relation alias as first parameter');
690
691		$q = AuthorQuery::create()
692			->joinBook('', Criteria::INNER_JOIN);
693		$q1 = AuthorQuery::create()
694			->join('Author.Book', Criteria::INNER_JOIN);
695		$this->assertTrue($q->equals($q1), 'joinRefFk() accepts a join type as second parameter');
696
697		$q = AuthorQuery::create()
698			->joinEssayRelatedBySecondAuthor();
699		$q1 = AuthorQuery::create()
700			->join('Author.EssayRelatedBySecondAuthor', Criteria::INNER_JOIN);
701		$this->assertTrue($q->equals($q1), 'joinRefFk() translates to a "INNER JOIN" when this is defined as defaultJoin in the schema');		
702	}
703	
704	public function testUseFkQuerySimple()
705	{
706		$q = BookQuery::create()
707			->useAuthorQuery()
708				->filterByFirstName('Leo')
709			->endUse();
710		$q1 = BookQuery::create()
711			->join('Book.Author', Criteria::LEFT_JOIN)
712			->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL);
713		$this->assertTrue($q->equals($q1), 'useFkQuery() translates to a condition on a left join on non-required columns');
714
715		$q = ReviewQuery::create()
716			->useBookQuery()
717				->filterByTitle('War And Peace')
718			->endUse();
719		$q1 = ReviewQuery::create()
720			->join('Review.Book', Criteria::INNER_JOIN)
721			->add(BookPeer::TITLE, 'War And Peace', Criteria::EQUAL);
722		$this->assertTrue($q->equals($q1), 'useFkQuery() translates to a condition on aninner join on required columns');
723	}
724
725	public function testUseFkQueryJoinType()
726	{
727		$q = BookQuery::create()
728			->useAuthorQuery(null, Criteria::LEFT_JOIN)
729				->filterByFirstName('Leo')
730			->endUse();
731		$q1 = BookQuery::create()
732			->join('Book.Author', Criteria::LEFT_JOIN)
733			->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL);
734		$this->assertTrue($q->equals($q1), 'useFkQuery() accepts a join type as second parameter');
735	}
736	
737	public function testUseFkQueryAlias()
738	{
739		$q = BookQuery::create()
740			->useAuthorQuery('a')
741				->filterByFirstName('Leo')
742			->endUse();
743		$join = new ModelJoin();
744		$join->setJoinType(Criteria::LEFT_JOIN);
745		$join->setTableMap(AuthorPeer::getTableMap());
746		$join->setRelationMap(BookPeer::getTableMap()->getRelation('Author'), null, 'a');
747		$join->setRelationAlias('a');
748		$q1 = BookQuery::create()
749			->addAlias('a', AuthorPeer::TABLE_NAME)
750			->addJoinObject($join, 'a')
751			->add('a.FIRST_NAME', 'Leo', Criteria::EQUAL);
752		$this->assertTrue($q->equals($q1), 'useFkQuery() uses the first argument as a table alias');
753	}
754
755	public function testUseFkQueryMixed()
756	{
757		$q = BookQuery::create()
758			->useAuthorQuery()
759				->filterByFirstName('Leo')
760			->endUse()
761			->filterByTitle('War And Peace');
762		$q1 = BookQuery::create()
763			->join('Book.Author', Criteria::LEFT_JOIN)
764			->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL)
765			->add(BookPeer::TITLE, 'War And Peace', Criteria::EQUAL);
766		$this->assertTrue($q->equals($q1), 'useFkQuery() allows combining conditions on main and related query');
767	}
768
769	public function testUseFkQueryTwice()
770	{
771		$q = BookQuery::create()
772			->useAuthorQuery()
773				->filterByFirstName('Leo')
774			->endUse()
775			->useAuthorQuery()
776				->filterByLastName('Tolstoi')
777			->endUse();
778		$q1 = BookQuery::create()
779			->join('Book.Author', Criteria::LEFT_JOIN)
780			->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL)
781			->add(AuthorPeer::LAST_NAME, 'Tolstoi', Criteria::EQUAL);
782		$this->assertTrue($q->equals($q1), 'useFkQuery() called twice on the same relation does not create two joins');
783	}
784
785	public function testUseFkQueryTwiceTwoAliases()
786	{
787		$q = BookQuery::create()
788			->useAuthorQuery('a')
789				->filterByFirstName('Leo')
790			->endUse()
791			->useAuthorQuery('b')
792				->filterByLastName('Tolstoi')
793			->endUse();
794		$join1 = new ModelJoin();
795		$join1->setJoinType(Criteria::LEFT_JOIN);
796		$join1->setTableMap(AuthorPeer::getTableMap());
797		$join1->setRelationMap(BookPeer::getTableMap()->getRelation('Author'), null, 'a');
798		$join1->setRelationAlias('a');
799		$join2 = new ModelJoin();
800		$join2->setJoinType(Criteria::LEFT_JOIN);
801		$join2->setTableMap(AuthorPeer::getTableMap());
802		$join2->setRelationMap(BookPeer::getTableMap()->getRelation('Author'), null, 'b');
803		$join2->setRelationAlias('b');
804		$q1 = BookQuery::create()
805			->addAlias('a', AuthorPeer::TABLE_NAME)
806			->addJoinObject($join1, 'a')
807			->add('a.FIRST_NAME', 'Leo', Criteria::EQUAL)
808			->addAlias('b', AuthorPeer::TABLE_NAME)
809			->addJoinObject($join2, 'b')
810			->add('b.LAST_NAME', 'Tolstoi', Criteria::EQUAL);
811		$this->assertTrue($q->equals($q1), 'useFkQuery() called twice on the same relation with two aliases creates two joins');
812	}
813
814	public function testUseFkQueryNested()
815	{
816		$q = ReviewQuery::create()
817			->useBookQuery()
818				->useAuthorQuery()
819					->filterByFirstName('Leo')
820				->endUse()
821			->endUse();
822		$q1 = ReviewQuery::create()
823			->join('Review.Book', Criteria::INNER_JOIN)
824			->join('Book.Author', Criteria::LEFT_JOIN)
825			->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL);
826		// embedded queries create joins that keep a relation to the parent
827		// as this is not testable, we need to use another testing technique
828		$params = array();
829		$result = BasePeer::createSelectSql($q, $params);
830		$expectedParams = array();
831		$expectedResult = BasePeer::createSelectSql($q1, $expectedParams);
832		$this->assertEquals($expectedParams, $params, 'useFkQuery() called nested creates two joins');
833		$this->assertEquals($expectedResult, $result, 'useFkQuery() called nested creates two joins');
834	}
835	
836	public function testUseFkQueryTwoRelations()
837	{
838		$q = BookQuery::create()
839			->useAuthorQuery()
840				->filterByFirstName('Leo')
841			->endUse()
842			->usePublisherQuery()
843				->filterByName('Penguin')
844			->endUse();
845		$q1 = BookQuery::create()
846			->join('Book.Author', Criteria::LEFT_JOIN)
847			->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL)
848			->join('Book.Publisher', Criteria::LEFT_JOIN)
849			->add(PublisherPeer::NAME, 'Penguin', Criteria::EQUAL);
850		$this->assertTrue($q->equals($q1), 'useFkQuery() called twice on two relations creates two joins');
851	}
852	
853	public function testPrune()
854	{
855		$q = BookQuery::create()->prune();
856		$this->assertTrue($q instanceof BookQuery, 'prune() returns the current Query object');
857	}
858	
859	public function testPruneSimpleKey()
860	{	
861		BookstoreDataPopulator::depopulate();
862		BookstoreDataPopulator::populate();
863		
864		$nbBooks = BookQuery::create()->prune()->count();
865		$this->assertEquals(4, $nbBooks, 'prune() does nothing when passed a null object');
866		
867		$testBook = BookQuery::create()->findOne();
868		$nbBooks = BookQuery::create()->prune($testBook)->count();
869		$this->assertEquals(3, $nbBooks, 'prune() removes an object from the result');
870	}
871
872	public function testPruneCompositeKey()
873	{
874		BookstoreDataPopulator::depopulate();
875		BookstoreDataPopulator::populate();
876		
877		// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
878		$c = new ModelCriteria('bookstore', 'Book');
879		$books = $c->find();
880		foreach ($books as $book) {
881			$book->save();
882		}
883		
884		BookPeer::clearInstancePool();
885		
886		$nbBookListRel = BookListRelQuery::create()->prune()->count();
887		$this->assertEquals(2, $nbBookListRel, 'prune() does nothing when passed a null object');
888		
889		$testBookListRel = BookListRelQuery::create()->findOne();
890		$nbBookListRel = BookListRelQuery::create()->prune($testBookListRel)->count();
891		$this->assertEquals(1, $nbBookListRel, 'prune() removes an object from the result');
892	}
893}
894
895class myCustomBookQuery extends BookQuery
896{
897	public static function create($modelAlias = null, $criteria = null)
898	{
899		if ($criteria instanceof myCustomBookQuery) {
900			return $criteria;
901		}
902		$query = new myCustomBookQuery();
903		if (null !== $modelAlias) {
904			$query->setModelAlias($modelAlias);
905		}
906		if ($criteria instanceof Criteria) {
907			$query->mergeWith($criteria);
908		}
909		return $query;
910	}
911	
912}