PageRenderTime 41ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/propel_14/vendor/propel/test/testsuite/generator/engine/builder/om/php5/GeneratedObjectTest.php

http://github.com/eventhorizonpl/forked-php-orm-benchmark
PHP | 1252 lines | 767 code | 251 blank | 234 comment | 10 complexity | 7b80303b6da3967094b71dff0147a359 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0
  1. <?php
  2. /*
  3. * $Id: GeneratedObjectTest.php 1639 2010-03-25 22:11:59Z francois $
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://propel.phpdb.org>.
  20. */
  21. require_once 'tools/helpers/bookstore/BookstoreEmptyTestBase.php';
  22. /**
  23. * Tests the generated Object classes.
  24. *
  25. * This test uses generated Bookstore classes to test the behavior of various
  26. * object operations. The _idea_ here is to test every possible generated method
  27. * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
  28. *
  29. * The database is relaoded before every test and flushed after every test. This
  30. * means that you can always rely on the contents of the databases being the same
  31. * for each test method in this class. See the BookstoreDataPopulator::populate()
  32. * method for the exact contents of the database.
  33. *
  34. * @see BookstoreDataPopulator
  35. * @author Hans Lellelid <hans@xmpl.org>
  36. * @package generator.engine.builder.om.php5
  37. */
  38. class GeneratedObjectTest extends BookstoreEmptyTestBase
  39. {
  40. protected function setUp()
  41. {
  42. parent::setUp();
  43. require_once 'tools/helpers/bookstore/behavior/TestAuthor.php';
  44. }
  45. /**
  46. * Test saving an object after setting default values for it.
  47. */
  48. public function testSaveWithDefaultValues()
  49. {
  50. // From the schema.xml, I am relying on the following:
  51. // - that 'Penguin' is the default Name for a Publisher
  52. // - that 2001-01-01 is the default ReviewDate for a Review
  53. // 1) check regular values (VARCHAR)
  54. $pub = new Publisher();
  55. $pub->setName('Penguin');
  56. $pub->save();
  57. $this->assertTrue($pub->getId() !== null, "Expect Publisher to have been saved when default value set.");
  58. // 2) check date/time values
  59. $review = new Review();
  60. // note that this is different from how it's represented in schema, but should resolve to same unix timestamp
  61. $review->setReviewDate('2001-01-01');
  62. $this->assertTrue($review->isModified(), "Expect Review to have been marked 'modified' after default date/time value set.");
  63. }
  64. /**
  65. * Test isModified() to be false after setting default value second time
  66. */
  67. public function testDefaultValueSetTwice()
  68. {
  69. $pub = new Publisher();
  70. $pub->setName('Penguin');
  71. $pub->save();
  72. $pubId = $pub->getId();
  73. PublisherPeer::clearInstancePool();
  74. $pub2 = PublisherPeer::retrieveByPK($pubId);
  75. $pub2->setName('Penguin');
  76. $this->assertFalse($pub2->isModified(), "Expect Publisher to be not modified after setting default value second time.");
  77. }
  78. public function testHasApplyDefaultValues()
  79. {
  80. $this->assertTrue(method_exists('Publisher', 'applyDefaultValues'), 'Tables with default values should have an applyDefaultValues() method');
  81. $this->assertFalse(method_exists('Book', 'applyDefaultValues'), 'Tables with no default values should not have an applyDefaultValues() method');
  82. }
  83. /**
  84. * Test default return values.
  85. */
  86. public function testDefaultValues()
  87. {
  88. $r = new Review();
  89. $this->assertEquals('2001-01-01', $r->getReviewDate('Y-m-d'));
  90. $this->assertFalse($r->isModified(), "expected isModified() to be false");
  91. $acct = new BookstoreEmployeeAccount();
  92. $this->assertEquals(true, $acct->getEnabled());
  93. $this->assertFalse($acct->isModified());
  94. $acct->setLogin("testuser");
  95. $acct->setPassword("testpass");
  96. $this->assertTrue($acct->isModified());
  97. }
  98. /**
  99. * Tests the use of default expressions and the reloadOnInsert and reloadOnUpdate attributes.
  100. *
  101. * @link http://propel.phpdb.org/trac/ticket/378
  102. * @link http://propel.phpdb.org/trac/ticket/555
  103. */
  104. public function testDefaultExpresions()
  105. {
  106. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  107. $this->markTestSkipped("Cannot test default expressions with SQLite");
  108. }
  109. $b = new Bookstore();
  110. $b->setStoreName("Foo!");
  111. $b->save();
  112. $employee = new BookstoreEmployee();
  113. $employee->setName("Johnny Walker");
  114. $acct = new BookstoreEmployeeAccount();
  115. $acct->setBookstoreEmployee($employee);
  116. $acct->setLogin("test-login");
  117. $this->assertNull($acct->getCreated(), "Expected created column to be NULL.");
  118. $this->assertNull($acct->getAuthenticator(), "Expected authenticator column to be NULL.");
  119. $acct->save();
  120. $acct = BookstoreEmployeeAccountPeer::retrieveByPK($acct->getEmployeeId());
  121. $this->assertNotNull($acct->getAuthenticator(), "Expected a valid (non-NULL) authenticator column after save.");
  122. $this->assertEquals('Password', $acct->getAuthenticator(), "Expected authenticator='Password' after save.");
  123. $this->assertNotNull($acct->getCreated(), "Expected a valid date after retrieving saved object.");
  124. $now = new DateTime("now");
  125. $this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
  126. $acct->setCreated($now);
  127. $this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
  128. // Unfortunately we can't really test the conjunction of reloadOnInsert and reloadOnUpdate when using just
  129. // default values. (At least not in a cross-db way.)
  130. }
  131. /**
  132. * Tests the use of default expressions and the reloadOnInsert attribute.
  133. *
  134. * @link http://propel.phpdb.org/trac/ticket/378
  135. * @link http://propel.phpdb.org/trac/ticket/555
  136. */
  137. public function testDefaultExpresions_ReloadOnInsert()
  138. {
  139. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  140. $this->markTestSkipped("Cannot test default date expressions with SQLite");
  141. }
  142. // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
  143. $b = new Bookstore();
  144. $b->setStoreName("Barnes & Noble");
  145. $b->save();
  146. $c = new Contest();
  147. $c->setName("Bookathon Contest");
  148. $c->save();
  149. $bc = new BookstoreContest();
  150. $bc->setBookstore($b);
  151. $bc->setContest($c);
  152. $bc->save();
  153. $c = new Customer();
  154. $c->setName("Happy Customer");
  155. $c->save();
  156. $bce = new BookstoreContestEntry();
  157. $bce->setBookstore($b);
  158. $bce->setBookstoreContest($bc);
  159. $bce->setCustomer($c);
  160. $bce->save();
  161. $this->assertNotNull($bce->getEntryDate(), "Expected a non-null entry_date after save.");
  162. }
  163. /**
  164. * Tests the overriding reloadOnInsert at runtime.
  165. *
  166. * @link http://propel.phpdb.org/trac/ticket/378
  167. * @link http://propel.phpdb.org/trac/ticket/555
  168. */
  169. public function testDefaultExpresions_ReloadOnInsert_Override()
  170. {
  171. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  172. $this->markTestSkipped("Cannot test default date expressions with SQLite");
  173. }
  174. // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
  175. $b = new Bookstore();
  176. $b->setStoreName("Barnes & Noble");
  177. $b->save();
  178. $c = new Contest();
  179. $c->setName("Bookathon Contest");
  180. $c->save();
  181. $bc = new BookstoreContest();
  182. $bc->setBookstore($b);
  183. $bc->setContest($c);
  184. $bc->save();
  185. $c = new Customer();
  186. $c->setName("Happy Customer");
  187. $c->save();
  188. $bce = new BookstoreContestEntry();
  189. $bce->setBookstore($b);
  190. $bce->setBookstoreContest($bc);
  191. $bce->setCustomer($c);
  192. $bce->save(null, $skipReload=true);
  193. $this->assertNull($bce->getEntryDate(), "Expected a NULL entry_date after save.");
  194. }
  195. /**
  196. * Tests the use of default expressions and the reloadOnUpdate attribute.
  197. *
  198. * @link http://propel.phpdb.org/trac/ticket/555
  199. */
  200. public function testDefaultExpresions_ReloadOnUpdate()
  201. {
  202. $b = new Bookstore();
  203. $b->setStoreName("Foo!");
  204. $b->save();
  205. $sale = new BookstoreSale();
  206. $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
  207. $sale->setSaleName("Spring Sale");
  208. $sale->save();
  209. // Expect that default values are set, but not default expressions
  210. $this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
  211. $sale->setSaleName("Winter Clearance");
  212. $sale->save();
  213. // Since reloadOnUpdate = true, we expect the discount to be set now.
  214. $this->assertNotNull($sale->getDiscount(), "Expected discount to be non-NULL after save.");
  215. }
  216. /**
  217. * Tests the overriding reloadOnUpdate at runtime.
  218. *
  219. * @link http://propel.phpdb.org/trac/ticket/378
  220. * @link http://propel.phpdb.org/trac/ticket/555
  221. */
  222. public function testDefaultExpresions_ReloadOnUpdate_Override()
  223. {
  224. $b = new Bookstore();
  225. $b->setStoreName("Foo!");
  226. $b->save();
  227. $sale = new BookstoreSale();
  228. $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
  229. $sale->setSaleName("Spring Sale");
  230. $sale->save();
  231. // Expect that default values are set, but not default expressions
  232. $this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
  233. $sale->setSaleName("Winter Clearance");
  234. $sale->save(null, $skipReload=true);
  235. // Since reloadOnUpdate = true, we expect the discount to be set now.
  236. $this->assertNull($sale->getDiscount(), "Expected NULL value for discount after save.");
  237. }
  238. /**
  239. * Test the behavior of date/time/values.
  240. * This requires that the model was built with propel.useDateTimeClass=true.
  241. */
  242. public function testTemporalValues_PreEpoch()
  243. {
  244. $r = new Review();
  245. $preEpochDate = new DateTime('1602-02-02');
  246. $r->setReviewDate($preEpochDate);
  247. $this->assertEquals('1602-02-02', $r->getReviewDate(null)->format("Y-m-d"));
  248. $r->setReviewDate('1702-02-02');
  249. $this->assertTrue($r->isModified());
  250. $this->assertEquals('1702-02-02', $r->getReviewDate(null)->format("Y-m-d"));
  251. // Now test for setting null
  252. $r->setReviewDate(null);
  253. $this->assertNull($r->getReviewDate());
  254. }
  255. /**
  256. * Test setting invalid date/time.
  257. */
  258. public function testSetTemporalValue_Invalid()
  259. {
  260. $this->markTestSkipped();
  261. // FIXME - Figure out why this doesn't work (causes a PHP ERROR instead of throwing Exception) in
  262. // the Phing+PHPUnit context
  263. $r = new Review();
  264. try {
  265. $r->setReviewDate("Invalid Date");
  266. $this->fail("Expected PropelException when setting date column w/ invalid date");
  267. } catch (PropelException $x) {
  268. print "Caught expected PropelException: " . $x->__toString();
  269. }
  270. }
  271. /**
  272. * Test setting TIMESTAMP columns w/ unix int timestamp.
  273. */
  274. public function testTemporalValues_Unix()
  275. {
  276. $store = new Bookstore();
  277. $store->setStoreName("test");
  278. $store->setStoreOpenTime(strtotime('12:55'));
  279. $store->save();
  280. $this->assertEquals('12:55', $store->getStoreOpenTime(null)->format('H:i'));
  281. $acct = new BookstoreEmployeeAccount();
  282. $acct->setCreated(time());
  283. $this->assertEquals(date('Y-m-d H:i'), $acct->getCreated('Y-m-d H:i'));
  284. $review = new Review();
  285. $review->setReviewDate(time());
  286. $this->assertEquals(date('Y-m-d'), $review->getReviewDate('Y-m-d'));
  287. }
  288. /**
  289. * Test setting empty temporal values.
  290. * @link http://propel.phpdb.org/trac/ticket/586
  291. */
  292. public function testTemporalValues_Empty()
  293. {
  294. $review = new Review();
  295. $review->setReviewDate('');
  296. $this->assertNull($review->getReviewDate());
  297. }
  298. /**
  299. * Test setting TIME columns.
  300. */
  301. public function testTemporalValues_TimeSetting()
  302. {
  303. $store = new Bookstore();
  304. $store->setStoreName("test");
  305. $store->setStoreOpenTime("12:55");
  306. $store->save();
  307. $store = new Bookstore();
  308. $store->setStoreName("test2");
  309. $store->setStoreOpenTime(new DateTime("12:55"));
  310. $store->save();
  311. }
  312. /**
  313. * Test setting TIME columns.
  314. */
  315. public function testTemporalValues_DateSetting()
  316. {
  317. BookstoreDataPopulator::populate();
  318. $r = new Review();
  319. $r->setBook(BookPeer::doSelectOne(new Criteria()));
  320. $r->setReviewDate(new DateTime('1999-12-20'));
  321. $r->setReviewedBy("Hans");
  322. $r->setRecommended(false);
  323. $r->save();
  324. }
  325. /**
  326. * Testing creating & saving new object & instance pool.
  327. */
  328. public function testObjectInstances_New()
  329. {
  330. $emp = new BookstoreEmployee();
  331. $emp->setName(md5(microtime()));
  332. $emp->save();
  333. $id = $emp->getId();
  334. $retrieved = BookstoreEmployeePeer::retrieveByPK($id);
  335. $this->assertSame($emp, $retrieved, "Expected same object (from instance pool)");
  336. }
  337. /**
  338. *
  339. */
  340. public function testObjectInstances_Fkeys()
  341. {
  342. // Establish a relationship between one employee and account
  343. // and then change the employee_id and ensure that the account
  344. // is not pulling the old employee.
  345. $pub1 = new Publisher();
  346. $pub1->setName('Publisher 1');
  347. $pub1->save();
  348. $pub2 = new Publisher();
  349. $pub2->setName('Publisher 2');
  350. $pub2->save();
  351. $book = new Book();
  352. $book->setTitle("Book Title");
  353. $book->setISBN("1234");
  354. $book->setPublisher($pub1);
  355. $book->save();
  356. $this->assertSame($pub1, $book->getPublisher());
  357. // now change values behind the scenes
  358. $con = Propel::getConnection(BookstoreEmployeeAccountPeer::DATABASE_NAME);
  359. $con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
  360. . " publisher_id = " . $pub2->getId()
  361. . " WHERE id = " . $book->getId());
  362. $book2 = BookPeer::retrieveByPK($book->getId());
  363. $this->assertSame($book, $book2, "Expected same book object instance");
  364. $this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have OLD publisher id before reload()");
  365. $book->reload();
  366. $this->assertEquals($pub2->getId(), $book->getPublisherId(), "Expected book to have new publisher id");
  367. $this->assertSame($pub2, $book->getPublisher(), "Expected book to have new publisher object associated.");
  368. // Now let's set it back, just to be double sure ...
  369. $con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
  370. . " publisher_id = " . $pub1->getId()
  371. . " WHERE id = " . $book->getId());
  372. $book->reload();
  373. $this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have old publisher id (again).");
  374. $this->assertSame($pub1, $book->getPublisher(), "Expected book to have old publisher object associated (again).");
  375. }
  376. /**
  377. * Test the effect of typecast on primary key values and instance pool retrieval.
  378. */
  379. public function testObjectInstancePoolTypecasting()
  380. {
  381. $reader = new BookReader();
  382. $reader->setName("Tester");
  383. $reader->save();
  384. $readerId = $reader->getId();
  385. $book = new Book();
  386. $book->setTitle("BookTest");
  387. $book->setISBN("TEST");
  388. $book->save();
  389. $bookId = $book->getId();
  390. $opinion = new BookOpinion();
  391. $opinion->setBookId((string)$bookId);
  392. $opinion->setReaderId((string)$readerId);
  393. $opinion->setRating(5);
  394. $opinion->setRecommendToFriend(false);
  395. $opinion->save();
  396. $opinion2 = BookOpinionPeer::retrieveByPK($bookId, $readerId);
  397. $this->assertSame($opinion, $opinion2, "Expected same object to be retrieved from differently type-casted primary key values.");
  398. }
  399. /**
  400. * Test the reload() method.
  401. */
  402. public function testReload()
  403. {
  404. BookstoreDataPopulator::populate();
  405. $a = AuthorPeer::doSelectOne(new Criteria());
  406. $origName = $a->getFirstName();
  407. $a->setFirstName(md5(time()));
  408. $this->assertNotEquals($origName, $a->getFirstName());
  409. $this->assertTrue($a->isModified());
  410. $a->reload();
  411. $this->assertEquals($origName, $a->getFirstName());
  412. $this->assertFalse($a->isModified());
  413. }
  414. /**
  415. * Test reload(deep=true) method.
  416. */
  417. public function testReloadDeep()
  418. {
  419. BookstoreDataPopulator::populate();
  420. // arbitrary book
  421. $b = BookPeer::doSelectOne(new Criteria());
  422. // arbitrary, different author
  423. $c = new Criteria();
  424. $c->add(AuthorPeer::ID, $b->getAuthorId(), Criteria::NOT_EQUAL);
  425. $a = AuthorPeer::doSelectOne($c);
  426. $origAuthor = $b->getAuthor();
  427. $b->setAuthor($a);
  428. $this->assertNotEquals($origAuthor, $b->getAuthor(), "Expected just-set object to be different from obj from DB");
  429. $this->assertTrue($b->isModified());
  430. $b->reload($deep=true);
  431. $this->assertEquals($origAuthor, $b->getAuthor(), "Expected object in DB to be restored");
  432. $this->assertFalse($a->isModified());
  433. }
  434. /**
  435. * Test saving an object and getting correct number of affected rows from save().
  436. * This includes tests of cascading saves to fk-related objects.
  437. */
  438. public function testSaveReturnValues()
  439. {
  440. $author = new Author();
  441. $author->setFirstName("Mark");
  442. $author->setLastName("Kurlansky");
  443. // do not save
  444. $pub = new Publisher();
  445. $pub->setName("Penguin Books");
  446. // do not save
  447. $book = new Book();
  448. $book->setTitle("Salt: A World History");
  449. $book->setISBN("0142001619");
  450. $book->setAuthor($author);
  451. $book->setPublisher($pub);
  452. $affected = $book->save();
  453. $this->assertEquals(3, $affected, "Expected 3 affected rows when saving book + publisher + author.");
  454. // change nothing ...
  455. $affected = $book->save();
  456. $this->assertEquals(0, $affected, "Expected 0 affected rows when saving already-saved book.");
  457. // modify the book (UPDATE)
  458. $book->setTitle("Salt A World History");
  459. $affected = $book->save();
  460. $this->assertEquals(1, $affected, "Expected 1 affected row when saving modified book.");
  461. // modify the related author
  462. $author->setLastName("Kurlanski");
  463. $affected = $book->save();
  464. $this->assertEquals(1, $affected, "Expected 1 affected row when saving book with updated author.");
  465. // modify both the related author and the book
  466. $author->setLastName("Kurlansky");
  467. $book->setTitle("Salt: A World History");
  468. $affected = $book->save();
  469. $this->assertEquals(2, $affected, "Expected 2 affected rows when saving updated book with updated author.");
  470. }
  471. /**
  472. * Test deleting an object using the delete() method.
  473. */
  474. public function testDelete()
  475. {
  476. BookstoreDataPopulator::populate();
  477. // 1) grab an arbitrary object
  478. $book = BookPeer::doSelectOne(new Criteria());
  479. $bookId = $book->getId();
  480. // 2) delete it
  481. $book->delete();
  482. // 3) make sure it can't be save()d now that it's deleted
  483. try {
  484. $book->setTitle("Will Fail");
  485. $book->save();
  486. $this->fail("Expect an exception to be thrown when attempting to save() a deleted object.");
  487. } catch (PropelException $e) {}
  488. // 4) make sure that it doesn't exist in db
  489. $book = BookPeer::retrieveByPK($bookId);
  490. $this->assertNull($book, "Expect NULL from retrieveByPK on deleted Book.");
  491. }
  492. /**
  493. *
  494. */
  495. public function testNoColsModified()
  496. {
  497. $e1 = new BookstoreEmployee();
  498. $e1->setName('Employee 1');
  499. $e2 = new BookstoreEmployee();
  500. $e2->setName('Employee 2');
  501. $super = new BookstoreEmployee();
  502. // we don't know who the supervisor is yet
  503. $super->addSubordinate($e1);
  504. $super->addSubordinate($e2);
  505. $affected = $super->save();
  506. }
  507. /**
  508. * Tests new one-to-one functionality.
  509. */
  510. public function testOneToOne()
  511. {
  512. BookstoreDataPopulator::populate();
  513. $emp = BookstoreEmployeePeer::doSelectOne(new Criteria());
  514. $acct = new BookstoreEmployeeAccount();
  515. $acct->setBookstoreEmployee($emp);
  516. $acct->setLogin("testuser");
  517. $acct->setPassword("testpass");
  518. $this->assertSame($emp->getBookstoreEmployeeAccount(), $acct, "Expected same object instance.");
  519. }
  520. /**
  521. * Test the type sensitivity of the resturning columns.
  522. *
  523. */
  524. public function testTypeSensitive()
  525. {
  526. BookstoreDataPopulator::populate();
  527. $book = BookPeer::doSelectOne(new Criteria());
  528. $r = new Review();
  529. $r->setReviewedBy("testTypeSensitive Tester");
  530. $r->setReviewDate(time());
  531. $r->setBook($book);
  532. $r->setRecommended(true);
  533. $r->save();
  534. $id = $r->getId();
  535. unset($r);
  536. // clear the instance cache to force reload from database.
  537. ReviewPeer::clearInstancePool();
  538. BookPeer::clearInstancePool();
  539. // reload and verify that the types are the same
  540. $r2 = ReviewPeer::retrieveByPK($id);
  541. $this->assertType('integer', $r2->getId(), "Expected getId() to return an integer.");
  542. $this->assertType('string', $r2->getReviewedBy(), "Expected getReviewedBy() to return a string.");
  543. $this->assertType('boolean', $r2->getRecommended(), "Expected getRecommended() to return a boolean.");
  544. $this->assertType('Book', $r2->getBook(), "Expected getBook() to return a Book.");
  545. $this->assertType('float', $r2->getBook()->getPrice(), "Expected Book->getPrice() to return a float.");
  546. $this->assertType('DateTime', $r2->getReviewDate(null), "Expected Book->getReviewDate() to return a DateTime.");
  547. }
  548. /**
  549. * This is a test for expected exceptions when saving UNIQUE.
  550. * See http://propel.phpdb.org/trac/ticket/2
  551. */
  552. public function testSaveUnique()
  553. {
  554. // The whole test is in a transaction, but this test needs real transactions
  555. $this->con->commit();
  556. $emp = new BookstoreEmployee();
  557. $emp->setName(md5(microtime()));
  558. $acct = new BookstoreEmployeeAccount();
  559. $acct->setBookstoreEmployee($emp);
  560. $acct->setLogin("foo");
  561. $acct->setPassword("bar");
  562. $acct->save();
  563. // now attempt to create a new acct
  564. $acct2 = $acct->copy();
  565. try {
  566. $acct2->save();
  567. $this->fail("Expected PropelException in first attempt to save object with duplicate value for UNIQUE constraint.");
  568. } catch (Exception $x) {
  569. try {
  570. // attempt to save it again
  571. $acct3 = $acct->copy();
  572. $acct3->save();
  573. $this->fail("Expected PropelException in second attempt to save object with duplicate value for UNIQUE constraint.");
  574. } catch (Exception $x) {
  575. // this is expected.
  576. }
  577. // now let's double check that it can succeed if we're not violating the constraint.
  578. $acct3->setLogin("foo2");
  579. $acct3->save();
  580. }
  581. $this->con->beginTransaction();
  582. }
  583. /**
  584. * Test for correct reporting of isModified().
  585. */
  586. public function testIsModified()
  587. {
  588. // 1) Basic test
  589. $a = new Author();
  590. $a->setFirstName("John");
  591. $a->setLastName("Doe");
  592. $a->setAge(25);
  593. $this->assertTrue($a->isModified(), "Expected Author to be modified after setting values.");
  594. $a->save();
  595. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  596. // 2) Test behavior with setting vars of different types
  597. // checking setting int col to string val
  598. $a->setAge('25');
  599. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after setting int column to string-cast of same value.");
  600. $a->setFirstName("John2");
  601. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing string column value.");
  602. // checking setting string col to int val
  603. $a->setFirstName("1");
  604. $a->save();
  605. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  606. $a->setFirstName(1);
  607. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after setting string column to int-cast of same value.");
  608. // 3) Test for appropriate behavior of NULL
  609. // checking "" -> NULL
  610. $a->setFirstName("");
  611. $a->save();
  612. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  613. $a->setFirstName(null);
  614. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing empty string column value to NULL.");
  615. $a->setFirstName("John");
  616. $a->setAge(0);
  617. $a->save();
  618. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  619. $a->setAge(null);
  620. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing 0-value int column to NULL.");
  621. $a->save();
  622. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  623. $a->setAge(0);
  624. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing NULL-value int column to 0.");
  625. }
  626. /**
  627. * Test the BaseObject#equals().
  628. */
  629. public function testEquals()
  630. {
  631. BookstoreDataPopulator::populate();
  632. $b = BookPeer::doSelectOne(new Criteria());
  633. $c = new Book();
  634. $c->setId($b->getId());
  635. $this->assertTrue($b->equals($c), "Expected Book objects to be equal()");
  636. $a = new Author();
  637. $a->setId($b->getId());
  638. $this->assertFalse($b->equals($a), "Expected Book and Author with same primary key NOT to match.");
  639. }
  640. /**
  641. * Test checking for non-default values.
  642. * @see http://propel.phpdb.org/trac/ticket/331
  643. */
  644. public function testHasOnlyDefaultValues()
  645. {
  646. $emp = new BookstoreEmployee();
  647. $emp->setName(md5(microtime()));
  648. $acct2 = new BookstoreEmployeeAccount();
  649. $acct = new BookstoreEmployeeAccount();
  650. $acct->setBookstoreEmployee($emp);
  651. $acct->setLogin("foo");
  652. $acct->setPassword("bar");
  653. $acct->save();
  654. $this->assertFalse($acct->isModified(), "Expected BookstoreEmployeeAccount NOT to be modified after save().");
  655. $acct->setEnabled(true);
  656. $acct->setPassword($acct2->getPassword());
  657. $this->assertTrue($acct->isModified(), "Expected BookstoreEmployeeAccount to be modified after setting default values.");
  658. $this->assertTrue($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to not have only default values.");
  659. $acct->setPassword("bar");
  660. $this->assertFalse($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to have at one non-default value after setting one value to non-default.");
  661. // Test a default date/time value
  662. $r = new Review();
  663. $r->setReviewDate(new DateTime("now"));
  664. $this->assertFalse($r->hasOnlyDefaultValues());
  665. }
  666. public function testDefaultFkColVal()
  667. {
  668. BookstoreDataPopulator::populate();
  669. $sale = new BookstoreSale();
  670. $this->assertEquals(1, $sale->getBookstoreId(), "Expected BookstoreSale object to have a default bookstore_id of 1.");
  671. $bookstore = BookstorePeer::doSelectOne(new Criteria());
  672. $sale->setBookstore($bookstore);
  673. $this->assertEquals($bookstore->getId(), $sale->getBookstoreId(), "Expected FK id to have changed when assigned a valid FK.");
  674. $sale->setBookstore(null);
  675. $this->assertEquals(1, $sale->getBookstoreId(), "Expected BookstoreSale object to have reset to default ID.");
  676. $sale->setPublisher(null);
  677. $this->assertEquals(null, $sale->getPublisherId(), "Expected BookstoreSale object to have reset to NULL publisher ID.");
  678. }
  679. public function testCountRefFk()
  680. {
  681. $book = new Book();
  682. $book->setTitle("Test Book");
  683. $book->setISBN("TT-EE-SS-TT");
  684. $num = 5;
  685. for ($i=2; $i < $num + 2; $i++) {
  686. $r = new Review();
  687. $r->setReviewedBy('Hans ' . $num);
  688. $dt = new DateTime("now");
  689. $dt->modify("-".$i." weeks");
  690. $r->setReviewDate($dt);
  691. $r->setRecommended(($i % 2) == 0);
  692. $book->addReview($r);
  693. }
  694. $this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num");
  695. $this->assertEquals($num, count($book->getReviews()), "Expected getReviews to return $num reviews");
  696. $book->save();
  697. BookPeer::clearInstancePool();
  698. ReviewPeer::clearInstancePool();
  699. $book = BookPeer::retrieveByPK($book->getId());
  700. $this->assertEquals($num, $book->countReviews(), "Expected countReviews() to return $num (after save)");
  701. $this->assertEquals($num, count($book->getReviews()), "Expected getReviews() to return $num (after save)");
  702. // Now set different criteria and expect different results
  703. $c = new Criteria();
  704. $c->add(ReviewPeer::RECOMMENDED, false);
  705. $this->assertEquals(floor($num/2), $book->countReviews($c), "Expected " . floor($num/2) . " results from countReviews(recomm=false)");
  706. // Change Criteria, run again -- expect different.
  707. $c = new Criteria();
  708. $c->add(ReviewPeer::RECOMMENDED, true);
  709. $this->assertEquals(ceil($num/2), count($book->getReviews($c)), "Expected " . ceil($num/2) . " results from getReviews(recomm=true)");
  710. $this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num with new empty Criteria");
  711. }
  712. /**
  713. * Test copyInto method.
  714. */
  715. public function testCopyInto_Deep()
  716. {
  717. BookstoreDataPopulator::populate();
  718. // Test a "normal" object
  719. $c = new Criteria();
  720. $c->add(BookPeer::TITLE, 'Harry%', Criteria::LIKE);
  721. $book = BookPeer::doSelectOne($c);
  722. $reviews = $book->getReviews();
  723. $b2 = $book->copy(true);
  724. $this->assertType('Book', $b2);
  725. $this->assertNull($b2->getId());
  726. $r2 = $b2->getReviews();
  727. $this->assertEquals(count($reviews), count($r2));
  728. // Test a one-to-one object
  729. $emp = BookstoreEmployeePeer::doSelectOne(new Criteria());
  730. $e2 = $emp->copy(true);
  731. $this->assertType('BookstoreEmployee', $e2);
  732. $this->assertNull($e2->getId());
  733. $this->assertEquals($emp->getBookstoreEmployeeAccount()->getLogin(), $e2->getBookstoreEmployeeAccount()->getLogin());
  734. }
  735. /**
  736. * Test copying when an object has composite primary key.
  737. * @link http://propel.phpdb.org/trac/ticket/618
  738. */
  739. public function testCopy_CompositePK()
  740. {
  741. $br = new BookReader();
  742. $br->setName("TestReader");
  743. $br->save();
  744. $br->copy();
  745. $b = new Book();
  746. $b->setTitle("TestBook");
  747. $b->setISBN("XX-XX-XX-XX");
  748. $b->save();
  749. $op = new BookOpinion();
  750. $op->setBookReader($br);
  751. $op->setBook($b);
  752. $op->setRating(10);
  753. $op->setRecommendToFriend(true);
  754. $op->save();
  755. $br2 = $br->copy(true);
  756. $this->assertNull($br2->getId());
  757. $opinions = $br2->getBookOpinions();
  758. $this->assertEquals(1, count($opinions), "Expected to have a related BookOpinion after copy()");
  759. // We DO expect the reader_id to be null
  760. $this->assertNull($opinions[0]->getReaderId());
  761. // but we DO NOT expect the book_id to be null
  762. $this->assertEquals($op->getBookId(), $opinions[0]->getBookId());
  763. }
  764. /**
  765. * Test the toArray() method with new lazyLoad param.
  766. * @link http://propel.phpdb.org/trac/ticket/527
  767. */
  768. public function testToArrayLazyLoad()
  769. {
  770. BookstoreDataPopulator::populate();
  771. $c = new Criteria();
  772. $c->add(MediaPeer::COVER_IMAGE, null, Criteria::NOT_EQUAL);
  773. $c->add(MediaPeer::EXCERPT, null, Criteria::NOT_EQUAL);
  774. $m = MediaPeer::doSelectOne($c);
  775. if ($m === null) {
  776. $this->fail("Test requires at least one media row w/ cover_image and excerpt NOT NULL");
  777. }
  778. $arr1 = $m->toArray(BasePeer::TYPE_COLNAME);
  779. $this->assertNotNull($arr1[MediaPeer::COVER_IMAGE]);
  780. $this->assertType('resource', $arr1[MediaPeer::COVER_IMAGE]);
  781. $arr2 = $m->toArray(BasePeer::TYPE_COLNAME, false);
  782. $this->assertNull($arr2[MediaPeer::COVER_IMAGE]);
  783. $this->assertNull($arr2[MediaPeer::EXCERPT]);
  784. $diffKeys = array_keys(array_diff($arr1, $arr2));
  785. $expectedDiff = array(MediaPeer::COVER_IMAGE, MediaPeer::EXCERPT);
  786. $this->assertEquals($expectedDiff, $diffKeys);
  787. }
  788. /**
  789. * Test regexp validator for ticket:542
  790. * @link http://propel.phpdb.org/trac/ticket/542
  791. */
  792. public function testRegexValidator()
  793. {
  794. $b = new Bookstore();
  795. $b->setWebsite("http://this.is.valid.com/foo.bar");
  796. $res = $b->validate();
  797. $this->assertTrue($res, "Expected URL to validate");
  798. }
  799. /**
  800. * Test that setting the auto-increment primary key will result in exception.
  801. */
  802. public function testSettingAutoIncrementPK()
  803. {
  804. // The whole test is in a transaction, but this test needs real transactions
  805. $this->con->commit();
  806. $b = new Bookstore();
  807. $b->setId(1);
  808. $b->setStoreName("Test");
  809. try {
  810. $b->save();
  811. $this->fail("Expected setting auto-increment primary key to result in Exception");
  812. } catch (Exception $x) {
  813. $this->assertType('PropelException', $x);
  814. }
  815. // ... but we should silently ignore NULL values, since these are really
  816. // the same as "not set" in PHP world.
  817. $b = new Bookstore();
  818. $b->setId(null);
  819. $b->setStoreName("Test2");
  820. try {
  821. $b->save();
  822. } catch (Exception $x) {
  823. $this->fail("Expected no exception when setting auto-increment primary key to NULL");
  824. }
  825. // success ...
  826. $this->con->beginTransaction();
  827. }
  828. /**
  829. * Checks wether we are allowed to specify the primary key on a
  830. * table with allowPkInsert=true set
  831. *
  832. * saves the object, gets it from data-source again and then compares
  833. * them for equality (thus the instance pool is also checked)
  834. */
  835. public function testAllowPkInsertOnIdMethodNativeTable()
  836. {
  837. $cu = new Customer;
  838. $cu->setPrimaryKey(100000);
  839. $cu->save();
  840. $cu2 = CustomerPeer::retrieveByPk(100000);
  841. $this->assertSame($cu, $cu2);
  842. }
  843. /**
  844. * Checks if it is allowed to save new, empty objects with a auto increment column
  845. */
  846. public function testAllowEmptyWithAutoIncrement()
  847. {
  848. $bookreader = new BookReader();
  849. $bookreader->save();
  850. $this->assertFalse($bookreader->isNew() );
  851. }
  852. /**
  853. * Test foreign key relationships based on references to unique cols but not PK.
  854. * @link http://propel.phpdb.org/trac/ticket/691
  855. */
  856. public function testUniqueFkRel()
  857. {
  858. $employee = new BookstoreEmployee();
  859. $employee->setName("Johnny Walker");
  860. $acct = new BookstoreEmployeeAccount();
  861. $acct->setBookstoreEmployee($employee);
  862. $acct->setLogin("test-login");
  863. $acct->save();
  864. $acctId = $acct->getEmployeeId();
  865. $al = new AcctAuditLog();
  866. $al->setBookstoreEmployeeAccount($acct);
  867. $al->save();
  868. $alId = $al->getId();
  869. BookstoreEmployeePeer::clearInstancePool();
  870. BookstoreEmployeeAccountPeer::clearInstancePool();
  871. AcctAuditLogPeer::clearInstancePool();
  872. $al2 = AcctAuditLogPeer::retrieveByPK($alId);
  873. /* @var $al2 AcctAuditLog */
  874. $mapacct = $al2->getBookstoreEmployeeAccount();
  875. $lookupacct = BookstoreEmployeeAccountPeer::retrieveByPK($acctId);
  876. $logs = $lookupacct->getAcctAuditLogs();
  877. $this->assertTrue(count($logs) == 1, "Expected 1 audit log result.");
  878. $this->assertEquals($logs[0]->getId(), $al->getId(), "Expected returned audit log to match created audit log.");
  879. }
  880. public function testAddPrimaryString()
  881. {
  882. $this->assertFalse(method_exists('Author', '__toString'), 'addPrimaryString() does not add a __toString() method if no column has the primaryString attribute');
  883. $this->assertTrue(method_exists('Book', '__toString'), 'addPrimaryString() adds a __toString() method if a column has the primaryString attribute');
  884. $book = new Book();
  885. $book->setTitle('foo');
  886. $this->assertEquals((string) $book, 'foo', 'addPrimaryString() adds a __toString() method returning the value of the the first column where primaryString is true');
  887. }
  888. public function testPreInsert()
  889. {
  890. $author = new TestAuthor();
  891. $author->setFirstName("bogus");
  892. $author->setLastName("Lastname");
  893. $author->save();
  894. $this->assertEquals('PreInsertedFirstname', $author->getFirstName());
  895. }
  896. public function testPreUpdate()
  897. {
  898. $author = new TestAuthor();
  899. $author->setFirstName("bogus");
  900. $author->setLastName("Lastname");
  901. $author->save();
  902. $author->setNew(false);
  903. $author->save();
  904. $this->assertEquals('PreUpdatedFirstname', $author->getFirstName());
  905. }
  906. public function testPostInsert()
  907. {
  908. $author = new TestAuthor();
  909. $author->setFirstName("bogus");
  910. $author->setLastName("Lastname");
  911. $author->save();
  912. $this->assertEquals('PostInsertedLastName', $author->getLastName());
  913. }
  914. public function testPostUpdate()
  915. {
  916. $author = new TestAuthor();
  917. $author->setFirstName("bogus");
  918. $author->setLastName("Lastname");
  919. $author->save();
  920. $author->setNew(false);
  921. $author->save();
  922. $this->assertEquals('PostUpdatedLastName', $author->getLastName());
  923. }
  924. public function testPreSave()
  925. {
  926. $author = new TestAuthor();
  927. $author->setFirstName("bogus");
  928. $author->setLastName("Lastname");
  929. $author->save();
  930. $this->assertEquals('pre@save.com', $author->getEmail());
  931. }
  932. public function testPreSaveFalse()
  933. {
  934. $con = Propel::getConnection(AuthorPeer::DATABASE_NAME);
  935. $author = new TestAuthorSaveFalse();
  936. $author->setFirstName("bogus");
  937. $author->setLastName("Lastname");
  938. $res = $author->save($con);
  939. $this->assertEquals(0, $res);
  940. $this->assertEquals('pre@save.com', $author->getEmail());
  941. $this->assertNotEquals(115, $author->getAge());
  942. $this->assertTrue($author->isNew());
  943. $this->assertEquals(1, $con->getNestedTransactionCount());
  944. }
  945. public function testPostSave()
  946. {
  947. $author = new TestAuthor();
  948. $author->setFirstName("bogus");
  949. $author->setLastName("Lastname");
  950. $author->save();
  951. $this->assertEquals(115, $author->getAge());
  952. }
  953. public function testPreDelete()
  954. {
  955. $author = new TestAuthor();
  956. $author->setFirstName("bogus");
  957. $author->setLastName("Lastname");
  958. $author->save();
  959. $author->delete();
  960. $this->assertEquals("Pre-Deleted", $author->getFirstName());
  961. }
  962. public function testPreDeleteFalse()
  963. {
  964. $con = Propel::getConnection(AuthorPeer::DATABASE_NAME);
  965. $author = new TestAuthorDeleteFalse();
  966. $author->setFirstName("bogus");
  967. $author->setLastName("Lastname");
  968. $author->save($con);
  969. $author->delete($con);
  970. $this->assertEquals("Pre-Deleted", $author->getFirstName());
  971. $this->assertNotEquals("Post-Deleted", $author->getLastName());
  972. $this->assertFalse($author->isDeleted());
  973. $this->assertEquals(1, $con->getNestedTransactionCount());
  974. }
  975. public function testPostDelete()
  976. {
  977. $author = new TestAuthor();
  978. $author->setFirstName("bogus");
  979. $author->setLastName("Lastname");
  980. $author->save();
  981. $author->delete();
  982. $this->assertEquals("Post-Deleted", $author->getLastName());
  983. }
  984. public static function conditionsForTestReadOnly()
  985. {
  986. return array(
  987. array('reload'),
  988. array('delete'),
  989. array('save'),
  990. array('doSave'),
  991. );
  992. }
  993. /**
  994. * @dataProvider conditionsForTestReadOnly
  995. */
  996. public function testReadOnly($method)
  997. {
  998. $cv = new ContestView();
  999. $this->assertFalse(method_exists($cv, $method), 'readOnly tables end up with no ' . $method . ' method in the generated object class');
  1000. }
  1001. }