PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/test/testsuite/generator/builder/om/GeneratedObjectTest.php

http://github.com/propelorm/Propel
PHP | 1733 lines | 1345 code | 235 blank | 153 comment | 13 complexity | 622397714ee1bf1e3cdeafa1e37ceca7 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. require_once dirname(__FILE__) . '/../../../../tools/helpers/bookstore/BookstoreTestBase.php';
  10. require_once dirname(__FILE__) . '/../../../../../generator/lib/util/PropelQuickBuilder.php';
  11. /**
  12. * Tests the generated Object classes.
  13. *
  14. * This test uses generated Bookstore classes to test the behavior of various
  15. * object operations. The _idea_ here is to test every possible generated method
  16. * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
  17. *
  18. * The database is reloaded before every test and flushed after every test. This
  19. * means that you can always rely on the contents of the databases being the same
  20. * for each test method in this class. See the BookstoreDataPopulator::populate()
  21. * method for the exact contents of the database.
  22. *
  23. * @see BookstoreDataPopulator
  24. * @author Hans Lellelid <hans@xmpl.org>
  25. * @package generator.builder.om
  26. */
  27. class GeneratedObjectTest extends BookstoreTestBase
  28. {
  29. protected function setUp()
  30. {
  31. parent::setUp();
  32. require_once dirname(__FILE__) . '/../../../../tools/helpers/bookstore/behavior/TestAuthor.php';
  33. }
  34. /**
  35. * Test saving an object after setting default values for it.
  36. */
  37. public function testSaveWithDefaultValues()
  38. {
  39. // From the schema.xml, I am relying on the following:
  40. // - that 'Penguin' is the default Name for a Publisher
  41. // - that 2001-01-01 is the default ReviewDate for a Review
  42. // 1) check regular values (VARCHAR)
  43. $pub = new Publisher();
  44. $pub->setName('Penguin');
  45. $pub->save();
  46. $this->assertTrue($pub->getId() !== null, "Expect Publisher to have been saved when default value set.");
  47. // 2) check date/time values
  48. $review = new Review();
  49. // note that this is different from how it's represented in schema, but should resolve to same unix timestamp
  50. $review->setReviewDate('2001-01-01');
  51. $this->assertTrue($review->isModified(), "Expect Review to have been marked 'modified' after default date/time value set.");
  52. }
  53. /**
  54. * Test isModified() to be false after setting default value second time
  55. */
  56. public function testDefaultValueSetTwice()
  57. {
  58. $pub = new Publisher();
  59. $pub->setName('Penguin');
  60. $pub->save();
  61. $pubId = $pub->getId();
  62. PublisherPeer::clearInstancePool();
  63. $pub2 = PublisherPeer::retrieveByPK($pubId);
  64. $pub2->setName('Penguin');
  65. $this->assertFalse($pub2->isModified(), "Expect Publisher to be not modified after setting default value second time.");
  66. }
  67. public function testHasApplyDefaultValues()
  68. {
  69. $this->assertTrue(method_exists('Publisher', 'applyDefaultValues'), 'Tables with default values should have an applyDefaultValues() method');
  70. $this->assertFalse(method_exists('Book', 'applyDefaultValues'), 'Tables with no default values should not have an applyDefaultValues() method');
  71. }
  72. /**
  73. * Test default return values.
  74. */
  75. public function testDefaultValues()
  76. {
  77. $r = new Review();
  78. $this->assertEquals('2001-01-01', $r->getReviewDate('Y-m-d'));
  79. $this->assertFalse($r->isModified(), "expected isModified() to be false");
  80. $acct = new BookstoreEmployeeAccount();
  81. $this->assertEquals(true, $acct->getEnabled());
  82. $this->assertFalse($acct->isModified());
  83. $acct->setLogin("testuser");
  84. $acct->setPassword("testpass");
  85. $this->assertTrue($acct->isModified());
  86. }
  87. public function testTypeHintingValues()
  88. {
  89. $test_name = 'test name';
  90. $a = new Author();
  91. $a2 = new Author();
  92. $a2->setFirstName($test_name);
  93. $a->setAge(2);
  94. $this->assertEquals(2, $a->getAge());
  95. $this->assertTrue(is_int($a->getAge()));
  96. $a->clear();
  97. $a->setAge('2');
  98. $this->assertEquals(2, $a->getAge());
  99. $this->assertTrue(is_int($a->getAge()));
  100. $a->clear();
  101. $a->setAge('wrong integer');
  102. $this->assertTrue(!is_int($a->getAge()));
  103. $a->clear();
  104. $a->setFirstName($test_name);
  105. $this->assertEquals($test_name, $a->getFirstName());
  106. $this->assertTrue(is_string($a->getFirstName()));
  107. $a->clear();
  108. $a->setFirstName($a2);
  109. $this->assertTrue(is_string($a->getFirstName()));
  110. $this->assertEquals($a->getFirstName(), (string) $a2);
  111. $a->clear();
  112. $a->setFirstName(true);
  113. $this->assertTrue(is_string($a->getFirstName()));
  114. }
  115. /**
  116. * Tests the use of default expressions and the reloadOnInsert and reloadOnUpdate attributes.
  117. *
  118. * @link http://trac.propelorm.org/ticket/378
  119. * @link http://trac.propelorm.org/ticket/555
  120. */
  121. public function testDefaultExpressions()
  122. {
  123. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  124. $this->markTestSkipped("Cannot test default expressions with SQLite");
  125. }
  126. BookstoreEmployeeAccountPeer::doDeleteAll();
  127. $b = new Bookstore();
  128. $b->setStoreName("Foo!");
  129. $b->save();
  130. $employee = new BookstoreEmployee();
  131. $employee->setName("Johnny Walker");
  132. $acct = new BookstoreEmployeeAccount();
  133. $acct->setBookstoreEmployee($employee);
  134. $acct->setLogin("test-login");
  135. $this->assertNull($acct->getCreated(), "Expected created column to be NULL.");
  136. $this->assertNull($acct->getAuthenticator(), "Expected authenticator column to be NULL.");
  137. $acct->save();
  138. $acct = BookstoreEmployeeAccountPeer::retrieveByPK($acct->getEmployeeId());
  139. $this->assertNotNull($acct->getAuthenticator(), "Expected a valid (non-NULL) authenticator column after save.");
  140. $this->assertEquals('Password', $acct->getAuthenticator(), "Expected authenticator='Password' after save.");
  141. $this->assertNotNull($acct->getCreated(), "Expected a valid date after retrieving saved object.");
  142. $now = new DateTime("now");
  143. $this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
  144. $acct->setCreated($now);
  145. $this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
  146. // Unfortunately we can't really test the conjunction of reloadOnInsert and reloadOnUpdate when using just
  147. // default values. (At least not in a cross-db way.)
  148. }
  149. /**
  150. * Tests the use of default expressions and the reloadOnInsert attribute.
  151. *
  152. * @link http://trac.propelorm.org/ticket/378
  153. * @link http://trac.propelorm.org/ticket/555
  154. */
  155. public function testDefaultExpresions_ReloadOnInsert()
  156. {
  157. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  158. $this->markTestSkipped("Cannot test default date expressions with SQLite");
  159. }
  160. // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
  161. $b = new Bookstore();
  162. $b->setStoreName("Barnes & Noble");
  163. $b->save();
  164. $c = new Contest();
  165. $c->setName("Bookathon Contest");
  166. $c->save();
  167. $bc = new BookstoreContest();
  168. $bc->setBookstore($b);
  169. $bc->setContest($c);
  170. $bc->save();
  171. $c = new Customer();
  172. $c->setName("Happy Customer");
  173. $c->save();
  174. $bce = new BookstoreContestEntry();
  175. $bce->setBookstore($b);
  176. $bce->setBookstoreContest($bc);
  177. $bce->setCustomer($c);
  178. $bce->save();
  179. $this->assertNotNull($bce->getEntryDate(), "Expected a non-null entry_date after save.");
  180. }
  181. /**
  182. * Tests the overriding reloadOnInsert at runtime.
  183. *
  184. * @link http://trac.propelorm.org/ticket/378
  185. * @link http://trac.propelorm.org/ticket/555
  186. */
  187. public function testDefaultExpresions_ReloadOnInsert_Override()
  188. {
  189. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  190. $this->markTestSkipped("Cannot test default date expressions with SQLite");
  191. }
  192. // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
  193. $b = new Bookstore();
  194. $b->setStoreName("Barnes & Noble");
  195. $b->save();
  196. $c = new Contest();
  197. $c->setName("Bookathon Contest");
  198. $c->save();
  199. $bc = new BookstoreContest();
  200. $bc->setBookstore($b);
  201. $bc->setContest($c);
  202. $bc->save();
  203. $c = new Customer();
  204. $c->setName("Happy Customer");
  205. $c->save();
  206. $bce = new BookstoreContestEntry();
  207. $bce->setBookstore($b);
  208. $bce->setBookstoreContest($bc);
  209. $bce->setCustomer($c);
  210. $bce->save(null, $skipReload=true);
  211. $this->assertNull($bce->getEntryDate(), "Expected a NULL entry_date after save.");
  212. }
  213. /**
  214. * Tests the use of default expressions and the reloadOnUpdate attribute.
  215. *
  216. * @link http://trac.propelorm.org/ticket/555
  217. */
  218. public function testDefaultExpresions_ReloadOnUpdate()
  219. {
  220. $b = new Bookstore();
  221. $b->setStoreName("Foo!");
  222. $b->save();
  223. $sale = new BookstoreSale();
  224. $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
  225. $sale->setSaleName("Spring Sale");
  226. $sale->save();
  227. // Expect that default values are set, but not default expressions
  228. $this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
  229. $sale->setSaleName("Winter Clearance");
  230. $sale->save();
  231. // Since reloadOnUpdate = true, we expect the discount to be set now.
  232. $this->assertNotNull($sale->getDiscount(), "Expected discount to be non-NULL after save.");
  233. }
  234. /**
  235. * Tests the overriding reloadOnUpdate at runtime.
  236. *
  237. * @link http://trac.propelorm.org/ticket/378
  238. * @link http://trac.propelorm.org/ticket/555
  239. */
  240. public function testDefaultExpresions_ReloadOnUpdate_Override()
  241. {
  242. $b = new Bookstore();
  243. $b->setStoreName("Foo!");
  244. $b->save();
  245. $sale = new BookstoreSale();
  246. $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
  247. $sale->setSaleName("Spring Sale");
  248. $sale->save();
  249. // Expect that default values are set, but not default expressions
  250. $this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
  251. $sale->setSaleName("Winter Clearance");
  252. $sale->save(null, $skipReload=true);
  253. // Since reloadOnUpdate = true, we expect the discount to be set now.
  254. $this->assertNull($sale->getDiscount(), "Expected NULL value for discount after save.");
  255. }
  256. /**
  257. * Testing creating & saving new object & instance pool.
  258. */
  259. public function testObjectInstances_New()
  260. {
  261. $emp = new BookstoreEmployee();
  262. $emp->setName(md5(microtime()));
  263. $emp->save();
  264. $id = $emp->getId();
  265. $retrieved = BookstoreEmployeePeer::retrieveByPK($id);
  266. $this->assertSame($emp, $retrieved, "Expected same object (from instance pool)");
  267. }
  268. /**
  269. *
  270. */
  271. public function testObjectInstances_Fkeys()
  272. {
  273. // Establish a relationship between one employee and account
  274. // and then change the employee_id and ensure that the account
  275. // is not pulling the old employee.
  276. $pub1 = new Publisher();
  277. $pub1->setName('Publisher 1');
  278. $pub1->save();
  279. $pub2 = new Publisher();
  280. $pub2->setName('Publisher 2');
  281. $pub2->save();
  282. $book = new Book();
  283. $book->setTitle("Book Title");
  284. $book->setISBN("1234");
  285. $book->setPublisher($pub1);
  286. $book->save();
  287. $this->assertSame($pub1, $book->getPublisher());
  288. // now change values behind the scenes
  289. $con = Propel::getConnection(BookstoreEmployeeAccountPeer::DATABASE_NAME);
  290. $con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
  291. . " publisher_id = " . $pub2->getId()
  292. . " WHERE id = " . $book->getId());
  293. $book2 = BookPeer::retrieveByPK($book->getId());
  294. $this->assertSame($book, $book2, "Expected same book object instance");
  295. $this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have OLD publisher id before reload()");
  296. $book->reload();
  297. $this->assertEquals($pub2->getId(), $book->getPublisherId(), "Expected book to have new publisher id");
  298. $this->assertSame($pub2, $book->getPublisher(), "Expected book to have new publisher object associated.");
  299. // Now let's set it back, just to be double sure ...
  300. $con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
  301. . " publisher_id = " . $pub1->getId()
  302. . " WHERE id = " . $book->getId());
  303. $book->reload();
  304. $this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have old publisher id (again).");
  305. $this->assertSame($pub1, $book->getPublisher(), "Expected book to have old publisher object associated (again).");
  306. }
  307. /**
  308. * Test the effect of typecast on primary key values and instance pool retrieval.
  309. */
  310. public function testObjectInstancePoolTypecasting()
  311. {
  312. $reader = new BookReader();
  313. $reader->setName("Tester");
  314. $reader->save();
  315. $readerId = $reader->getId();
  316. $book = new Book();
  317. $book->setTitle("BookTest");
  318. $book->setISBN("TEST");
  319. $book->save();
  320. $bookId = $book->getId();
  321. $opinion = new BookOpinion();
  322. $opinion->setBookId((string) $bookId);
  323. $opinion->setReaderId((string) $readerId);
  324. $opinion->setRating(5);
  325. $opinion->setRecommendToFriend(false);
  326. $opinion->save();
  327. $opinion2 = BookOpinionPeer::retrieveByPK($bookId, $readerId);
  328. $this->assertSame($opinion, $opinion2, "Expected same object to be retrieved from differently type-casted primary key values.");
  329. }
  330. /**
  331. * Test saving an object and getting correct number of affected rows from save().
  332. * This includes tests of cascading saves to fk-related objects.
  333. */
  334. public function testSaveReturnValues()
  335. {
  336. $author = new Author();
  337. $author->setFirstName("Mark");
  338. $author->setLastName("Kurlansky");
  339. // do not save
  340. $pub = new Publisher();
  341. $pub->setName("Penguin Books");
  342. // do not save
  343. $book = new Book();
  344. $book->setTitle("Salt: A World History");
  345. $book->setISBN("0142001619");
  346. $book->setAuthor($author);
  347. $book->setPublisher($pub);
  348. $affected = $book->save();
  349. $this->assertEquals(3, $affected, "Expected 3 affected rows when saving book + publisher + author.");
  350. // change nothing ...
  351. $affected = $book->save();
  352. $this->assertEquals(0, $affected, "Expected 0 affected rows when saving already-saved book.");
  353. // modify the book (UPDATE)
  354. $book->setTitle("Salt A World History");
  355. $affected = $book->save();
  356. $this->assertEquals(1, $affected, "Expected 1 affected row when saving modified book.");
  357. // modify the related author
  358. $author->setLastName("Kurlanski");
  359. $affected = $book->save();
  360. $this->assertEquals(1, $affected, "Expected 1 affected row when saving book with updated author.");
  361. // modify both the related author and the book
  362. $author->setLastName("Kurlansky");
  363. $book->setTitle("Salt: A World History");
  364. $affected = $book->save();
  365. $this->assertEquals(2, $affected, "Expected 2 affected rows when saving updated book with updated author.");
  366. }
  367. /*
  368. WTF!!!!!!
  369. public function testSaveCanInsertEmptyObjects()
  370. {
  371. $b = new Book();
  372. $b->save();
  373. $this->assertFalse($b->isNew());
  374. $this->assertNotNull($b->getId());
  375. }
  376. */
  377. public function testSaveCanInsertNonEmptyObjects()
  378. {
  379. $b = new Book();
  380. $b->setTitle('foo');
  381. $b->setIsbn('124');
  382. $b->save();
  383. $this->assertFalse($b->isNew());
  384. $this->assertNotNull($b->getId());
  385. }
  386. /**
  387. *
  388. */
  389. public function testNoColsModified()
  390. {
  391. $e1 = new BookstoreEmployee();
  392. $e1->setName('Employee 1');
  393. $e2 = new BookstoreEmployee();
  394. $e2->setName('Employee 2');
  395. $super = new BookstoreEmployee();
  396. // we don't know who the supervisor is yet
  397. $super->addSubordinate($e1);
  398. $super->addSubordinate($e2);
  399. $affected = $super->save();
  400. }
  401. public function testIsModifiedIsFalseForNewObjects()
  402. {
  403. $a = new Author();
  404. $this->assertFalse($a->isModified());
  405. }
  406. public function testIsModifiedIsTrueForNewObjectsWithModifications()
  407. {
  408. $a = new Author();
  409. $a->setFirstName('Foo');
  410. $this->assertTrue($a->isModified());
  411. }
  412. public function testIsModifiedIsFalseForNewObjectsWithNullModifications()
  413. {
  414. $a = new Author();
  415. $a->setFirstName(null);
  416. $this->assertFalse($a->isModified());
  417. }
  418. public function testIsModifiedIsFalseForObjectsAfterResetModified()
  419. {
  420. $a = new Author();
  421. $a->setFirstName('Foo');
  422. $a->resetModified();
  423. $this->assertFalse($a->isModified());
  424. }
  425. public function testIsModifiedIsFalseForSavedObjects()
  426. {
  427. $a = new Author();
  428. $a->setFirstName('Foo');
  429. $a->setLastName('Bar');
  430. $a->save();
  431. $this->assertFalse($a->isModified());
  432. }
  433. public function testIsModifiedIsTrueForSavedObjectsWithModifications()
  434. {
  435. $a = new Author();
  436. $a->setFirstName('Foo');
  437. $this->assertTrue($a->isModified());
  438. }
  439. public function testIsModifiedIsFalseAfterSetToDefaultValueOnNewObject()
  440. {
  441. $p = new Publisher();
  442. $p->setName('Penguin'); // default column value
  443. $this->assertFalse($p->isModified());
  444. }
  445. public function testIsModifiedIsTrueAfterModifyingOnNonDefaultValueOnNewObject()
  446. {
  447. $p = new Publisher();
  448. $p->setName('Puffin Books');
  449. $this->assertTrue($p->isModified());
  450. }
  451. public function testIsModifiedIsTrueAfterSetToDefaultValueOnModifiedObject()
  452. {
  453. $p = new Publisher();
  454. $p->setName('Puffin Books');
  455. $p->resetModified();
  456. $p->setName('Penguin'); // default column value
  457. $this->assertTrue($p->isModified());
  458. }
  459. public function testIsModifiedIsFalseAfterChangingColumnTypeButNotValue()
  460. {
  461. $a = new Author();
  462. $a->setFirstName('1');
  463. $a->setAge(25);
  464. $a->resetModified();
  465. $a->setAge('25');
  466. $this->assertFalse($a->isModified());
  467. $a->setFirstName(1);
  468. $this->assertFalse($a->isModified());
  469. }
  470. public function testIsModifiedAndNullValues()
  471. {
  472. $a = new Author();
  473. $a->setFirstName('');
  474. $a->setLastName('Bar');
  475. $a->setAge(0);
  476. $a->save();
  477. $a->setFirstName(null);
  478. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing empty string column value to NULL.");
  479. $a->setAge(null);
  480. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing 0-value int column to NULL.");
  481. $a->setFirstName('');
  482. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing NULL column value to empty string.");
  483. $a->setAge(0);
  484. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing NULL column to 0-value int.");
  485. }
  486. /**
  487. * Test checking for non-default values.
  488. * @see http://trac.propelorm.org/ticket/331
  489. */
  490. public function testHasOnlyDefaultValues()
  491. {
  492. $emp = new BookstoreEmployee();
  493. $emp->setName(md5(microtime()));
  494. $acct2 = new BookstoreEmployeeAccount();
  495. $acct = new BookstoreEmployeeAccount();
  496. $acct->setBookstoreEmployee($emp);
  497. $acct->setLogin("foo");
  498. $acct->setPassword("bar");
  499. $acct->save();
  500. $this->assertFalse($acct->isModified(), "Expected BookstoreEmployeeAccount NOT to be modified after save().");
  501. $acct->setEnabled(true);
  502. $acct->setPassword($acct2->getPassword());
  503. $this->assertTrue($acct->isModified(), "Expected BookstoreEmployeeAccount to be modified after setting default values.");
  504. $this->assertTrue($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to not have only default values.");
  505. $acct->setPassword("bar");
  506. $this->assertFalse($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to have at one non-default value after setting one value to non-default.");
  507. // Test a default date/time value
  508. $r = new Review();
  509. $r->setReviewDate(new DateTime("now"));
  510. $this->assertFalse($r->hasOnlyDefaultValues());
  511. }
  512. public function testCountRefFk()
  513. {
  514. $book = new Book();
  515. $book->setTitle("Test Book");
  516. $book->setISBN("TT-EE-SS-TT");
  517. $num = 5;
  518. for ($i=2; $i < $num + 2; $i++) {
  519. $r = new Review();
  520. $r->setReviewedBy('Hans ' . $num);
  521. $dt = new DateTime("now");
  522. $dt->modify("-".$i." weeks");
  523. $r->setReviewDate($dt);
  524. $r->setRecommended(($i % 2) == 0);
  525. $book->addReview($r);
  526. }
  527. $this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num");
  528. $this->assertEquals($num, count($book->getReviews()), "Expected getReviews to return $num reviews");
  529. $book->save();
  530. BookPeer::clearInstancePool();
  531. ReviewPeer::clearInstancePool();
  532. $book = BookPeer::retrieveByPK($book->getId());
  533. $this->assertEquals($num, $book->countReviews(), "Expected countReviews() to return $num (after save)");
  534. $this->assertEquals($num, count($book->getReviews()), "Expected getReviews() to return $num (after save)");
  535. // Now set different criteria and expect different results
  536. $c = new Criteria();
  537. $c->add(ReviewPeer::RECOMMENDED, false);
  538. $this->assertEquals(floor($num/2), $book->countReviews($c), "Expected " . floor($num/2) . " results from countReviews(recomm=false)");
  539. // Change Criteria, run again -- expect different.
  540. $c = new Criteria();
  541. $c->add(ReviewPeer::RECOMMENDED, true);
  542. $this->assertEquals(ceil($num/2), count($book->getReviews($c)), "Expected " . ceil($num/2) . " results from getReviews(recomm=true)");
  543. $this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num with new empty Criteria");
  544. }
  545. /**
  546. * Test copying when an object has composite primary key.
  547. * @link http://trac.propelorm.org/ticket/618
  548. */
  549. public function testCopy_CompositePK()
  550. {
  551. $br = new BookReader();
  552. $br->setName("TestReader");
  553. $br->save();
  554. $br->copy();
  555. $b = new Book();
  556. $b->setTitle("TestBook");
  557. $b->setISBN("XX-XX-XX-XX");
  558. $b->save();
  559. $op = new BookOpinion();
  560. $op->setBookReader($br);
  561. $op->setBook($b);
  562. $op->setRating(10);
  563. $op->setRecommendToFriend(true);
  564. $op->save();
  565. $br2 = $br->copy(true);
  566. $this->assertNull($br2->getId());
  567. $opinions = $br2->getBookOpinions();
  568. $this->assertEquals(1, count($opinions), "Expected to have a related BookOpinion after copy()");
  569. // We DO expect the reader_id to be null
  570. $this->assertNull($opinions[0]->getReaderId());
  571. // but we DO NOT expect the book_id to be null
  572. $this->assertEquals($op->getBookId(), $opinions[0]->getBookId());
  573. }
  574. /**
  575. * When a relation PK is a composite, replacing the list of relations will flag some of them to be deleted.
  576. * We primary keys on the "To be deleted" opinions must not be blanked (null) because we need to values to be able to delete the entry.
  577. */
  578. public function testReplace_RelationWithCompositePK()
  579. {
  580. BookReaderQuery::create()->deleteAll();
  581. BookQuery::create()->deleteAll();
  582. BookOpinionQuery::create()->deleteAll();
  583. $br1 = new BookReader();
  584. $br1->setName("TestReader");
  585. $br1->save();
  586. $br2 = new BookReader();
  587. $br2->setName("TestReader2");
  588. $br2->save();
  589. $b = new Book();
  590. $b->setTitle("TestBook");
  591. $b->setISBN("XX-XX-XX-XX");
  592. $b->save();
  593. $op1 = new BookOpinion();
  594. $op1->setBookReader($br1);
  595. $op1->setBook($b);
  596. $op1->setRating(10);
  597. $op1->setRecommendToFriend(true);
  598. $op1->save();
  599. // make sure everything is loaded correctly (and their relation too)
  600. $br1->reload(true);
  601. $b->reload(true);
  602. $op1->reload(true);
  603. $br2->reload(true);
  604. $op2 = new BookOpinion();
  605. $op2->setBookReader($br2);
  606. $op2->setRating(8);
  607. $op2->setRecommendToFriend(false);
  608. // the setBookOpinions function expect a PropelCollection
  609. $pc = new PropelObjectCollection();
  610. $pc->setModel('BookOpinion');
  611. $pc->append($op2);
  612. $br1->getBookOpinions(); // load the relation
  613. $b->setBookOpinions($pc); // this will flag to be deleted the currently assigned opinion and will add the new opinion so it will can be saved
  614. $b->save(); // this will delete $op1 and insert $op2
  615. $this->assertEquals(2, BookReaderQuery::create()->count(), '2 BookReader');
  616. $this->assertEquals(1, BookQuery::create()->count(), '1 Book');
  617. $this->assertEquals(1, BookOpinionQuery::create()->count(), 'Only 1 BookOpinion; the new one got inserted and the previously associated one got deleted');
  618. $this->assertEquals(1, count($b->getBookOpinions()), 'Book has 1 BookOpinion');
  619. $this->assertEquals(1, count($op2->getBook()), 'BookOpinion2 has a relation to the Book');
  620. $this->assertEquals(1, count($br1->getBookOpinions()), 'BookReader1 has 1 BookOpinion (BookOpinion1)');
  621. $this->assertEquals(1, count($br2->getBookOpinions()), 'BookReader2 has 1 BookOpinion (BookOpinion2)');
  622. $this->assertFalse($op1->isDeleted(), 'BookOpinion1 think it has not been deleted');
  623. $caughtException = false;
  624. try {
  625. $op1->reload(false); // will fail because won't find the entry in the db
  626. } catch (PropelException $pe) {
  627. $caughtException = true;
  628. }
  629. $this->assertTrue($caughtException, 'Could not reload BookOpinion1 because it has been deleted from the db');
  630. $this->assertFalse($op2->isDeleted(), 'BookOpinion2 is not deleted');
  631. $this->assertEquals(1, count($br1->getBookOpinions()), 'BookReader1 thinks it is assigned to 1 BookOpinion (BookOpinion1)');
  632. $temp_op = $br1->getBookOpinions();
  633. $this->assertEquals(spl_object_hash($op1), spl_object_hash($temp_op[0]), 'BookReader1 assigned BookOpinion is still BookOpinion1');
  634. $this->assertFalse($temp_op[0]->isDeleted(), 'BookReader1 assigned BookOpinion still thinks it has not been deleted');
  635. $br1->reload(true); // and reset the relations
  636. $this->assertEquals(0, count($br1->getBookOpinions()), 'BookReader1 no longer has any BookOpinion');
  637. }
  638. /**
  639. * Test removing object when FK is part of the composite PK
  640. */
  641. public function testRemove_CompositePK()
  642. {
  643. BookReaderQuery::create()->deleteAll();
  644. BookQuery::create()->deleteAll();
  645. BookOpinionQuery::create()->deleteAll();
  646. $br = new BookReader();
  647. $br->setName("TestReader");
  648. $br->save();
  649. $b = new Book();
  650. $b->setTitle("TestBook");
  651. $b->setISBN("XX-XX-XX-XX");
  652. $b->save();
  653. $op = new BookOpinion();
  654. $op->setBookReader($br);
  655. $op->setBook($b);
  656. $op->setRating(10);
  657. $op->setRecommendToFriend(true);
  658. $op->save();
  659. $this->assertEquals(1, BookReaderQuery::create()->count(), '1 BookReader');
  660. $this->assertEquals(1, BookQuery::create()->count(), '1 Book');
  661. $this->assertEquals(1, BookOpinionQuery::create()->count(), '1 BookOpinion');
  662. // make sure everything is loaded correctly (and their relation too)
  663. $br->reload(true);
  664. $b->reload(true);
  665. $op->reload(true);
  666. $br->getBookOpinions(); // load the relation
  667. $b->removeBookOpinion($op);
  668. $b->save();
  669. // the Book knows that there is no longer an opinion
  670. $this->assertEquals(0, count($b->getBookOpinions()), 'Book knows there is no opinion');
  671. // but not the BookReader
  672. $this->assertEquals(1, count($br->getBookOpinions()), 'BookReader still thinks it has 1 opinion');
  673. $br->reload(true); // with relations
  674. $this->assertEquals(0, count($br->getBookOpinions()), 'BookReader now knows the opinion is gone');
  675. $this->assertEquals(1, BookReaderQuery::create()->count(), '1 BookReader');
  676. $this->assertEquals(1, BookQuery::create()->count(), '1 Book');
  677. $this->assertEquals(0, BookOpinionQuery::create()->count(), '0 BookOpinion');
  678. }
  679. /**
  680. *
  681. */
  682. public function testCopyConcretInheritance()
  683. {
  684. $concreteArticle = new ConcreteArticle();
  685. $concreteArticle->setBody('TestBody');
  686. $concreteArticle->save();
  687. $copy = $concreteArticle->copy();
  688. $this->assertNull($copy->getId(), "single PK not autoincremented shouldn't be copied");
  689. }
  690. public function testDeepCopyConcretInheritance()
  691. {
  692. $comment1 = new ConcreteComment();
  693. $comment1->setMessage('my-new-comment1');
  694. $concreteArticle = new ConcreteArticle();
  695. $concreteArticle->setBody('TestBody');
  696. $concreteArticle->addConcreteComment($comment1);
  697. $concreteArticle->save();
  698. $comment1->save();
  699. $this->assertNotNull($comment1->getId());
  700. $this->assertNotNull($concreteArticle->getId());
  701. $this->assertEquals(1, $concreteArticle->countConcreteComments());
  702. $this->assertEquals($comment1->getConcreteContentId(), $concreteArticle->getId());
  703. $copy = $concreteArticle->copy(true);
  704. $this->assertNull($copy->getId());
  705. $this->assertEquals(1, $concreteArticle->countConcreteComments());
  706. $comments = $copy->getConcreteContent()->getConcreteComments();
  707. $this->assertEquals('my-new-comment1', $comments[0]->getMessage());
  708. }
  709. public function testToArray()
  710. {
  711. $b = new Book();
  712. $b->setTitle('Don Juan');
  713. $arr1 = $b->toArray();
  714. $expectedKeys = array(
  715. 'Id',
  716. 'Title',
  717. 'ISBN',
  718. 'Price',
  719. 'PublisherId',
  720. 'AuthorId'
  721. );
  722. $this->assertEquals($expectedKeys, array_keys($arr1), 'toArray() returns an associative array with BasePeer::TYPE_PHPNAME keys by default');
  723. $this->assertEquals('Don Juan', $arr1['Title'], 'toArray() returns an associative array representation of the object');
  724. }
  725. public function testToArrayWithColumn()
  726. {
  727. $book = BookQuery::create()->withColumn('Title', 'TitleCopy')->findOne();
  728. $bookArray = $book->toArray();
  729. $this->assertEquals($book->getTitleCopy(), $bookArray['TitleCopy']);
  730. }
  731. public function testToArrayKeyType()
  732. {
  733. $b = new Book();
  734. $b->setTitle('Don Juan');
  735. $arr1 = $b->toArray(BasePeer::TYPE_COLNAME);
  736. $expectedKeys = array(
  737. BookPeer::ID,
  738. BookPeer::TITLE,
  739. BookPeer::ISBN,
  740. BookPeer::PRICE,
  741. BookPeer::PUBLISHER_ID,
  742. BookPeer::AUTHOR_ID
  743. );
  744. $this->assertEquals($expectedKeys, array_keys($arr1), 'toArray() accepts a $keyType parameter to change the result keys');
  745. $this->assertEquals('Don Juan', $arr1[BookPeer::TITLE], 'toArray() returns an associative array representation of the object');
  746. }
  747. public function testToArrayKeyTypePreDefined()
  748. {
  749. $schema = <<<EOF
  750. <database name="test">
  751. <table name="test_key_type_table">
  752. <column name="id_key_type" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  753. <column name="name_key_type" type="VARCHAR" />
  754. </table>
  755. </database>
  756. EOF;
  757. $builder = new PropelQuickBuilder();
  758. $builder->setSchema($schema);
  759. $builder->getConfig()->setBuildProperty('defaultKeyType', 'studlyPhpName');
  760. $builder->buildClasses();
  761. $expectedKeys = array(
  762. 'idKeyType',
  763. 'nameKeyType',
  764. );
  765. $object = new TestKeyTypeTable();
  766. $this->assertEquals($expectedKeys, array_keys($object->toArray()), 'toArray() returns an associative array with pre-defined key type in properties.');
  767. }
  768. /**
  769. * Test regexp validator for ticket:542
  770. * @link http://trac.propelorm.org/ticket/542
  771. */
  772. public function testRegexValidator()
  773. {
  774. $b = new Bookstore();
  775. $b->setWebsite("http://this.is.valid.com/foo.bar");
  776. $res = $b->validate();
  777. $this->assertTrue($res, "Expected URL to validate");
  778. }
  779. /**
  780. * Test that setting the auto-increment primary key will result in exception.
  781. */
  782. public function testSettingAutoIncrementPK()
  783. {
  784. // The whole test is in a transaction, but this test needs real transactions
  785. $this->con->commit();
  786. $b = new Bookstore();
  787. $b->setId(1);
  788. $b->setStoreName("Test");
  789. try {
  790. $b->save();
  791. $this->fail("Expected setting auto-increment primary key to result in Exception");
  792. } catch (Exception $x) {
  793. $this->assertInstanceOf('PropelException', $x);
  794. }
  795. // ... but we should silently ignore NULL values, since these are really
  796. // the same as "not set" in PHP world.
  797. $b = new Bookstore();
  798. $b->setId(null);
  799. $b->setStoreName("Test2");
  800. try {
  801. $b->save();
  802. } catch (Exception $x) {
  803. $this->fail("Expected no exception when setting auto-increment primary key to NULL");
  804. }
  805. // success ...
  806. $this->con->beginTransaction();
  807. }
  808. /**
  809. * Checks wether we are allowed to specify the primary key on a
  810. * table with allowPkInsert=true set
  811. *
  812. * saves the object, gets it from data-source again and then compares
  813. * them for equality (thus the instance pool is also checked)
  814. */
  815. public function testAllowPkInsertOnIdMethodNativeTable()
  816. {
  817. CustomerPeer::doDeleteAll();
  818. $cu = new Customer;
  819. $cu->setPrimaryKey(100000);
  820. $cu->save();
  821. $this->assertEquals(100000, $cu->getPrimaryKey());
  822. $cu2 = CustomerPeer::retrieveByPk(100000);
  823. $this->assertSame($cu, $cu2);
  824. }
  825. /**
  826. * Checks if it is allowed to save new, empty objects with a auto increment column
  827. */
  828. public function testAllowEmptyWithAutoIncrement()
  829. {
  830. $bookreader = new BookReader();
  831. $bookreader->save();
  832. $this->assertFalse($bookreader->isNew());
  833. }
  834. /**
  835. * Test foreign key relationships based on references to unique cols but not PK.
  836. * @link http://trac.propelorm.org/ticket/691
  837. */
  838. public function testUniqueFkRel()
  839. {
  840. BookstoreEmployeeAccountPeer::doDeleteAll();
  841. $employee = new BookstoreEmployee();
  842. $employee->setName("Johnny Walker");
  843. $acct = new BookstoreEmployeeAccount();
  844. $acct->setBookstoreEmployee($employee);
  845. $acct->setLogin("test-login");
  846. $acct->save();
  847. $acctId = $acct->getEmployeeId();
  848. $al = new AcctAuditLog();
  849. $al->setBookstoreEmployeeAccount($acct);
  850. $al->save();
  851. $alId = $al->getId();
  852. BookstoreEmployeePeer::clearInstancePool();
  853. BookstoreEmployeeAccountPeer::clearInstancePool();
  854. AcctAuditLogPeer::clearInstancePool();
  855. $al2 = AcctAuditLogPeer::retrieveByPK($alId);
  856. /* @var $al2 AcctAuditLog */
  857. $mapacct = $al2->getBookstoreEmployeeAccount();
  858. $lookupacct = BookstoreEmployeeAccountPeer::retrieveByPK($acctId);
  859. $logs = $lookupacct->getAcctAuditLogs();
  860. $this->assertTrue(count($logs) == 1, "Expected 1 audit log result.");
  861. $this->assertEquals($logs[0]->getId(), $al->getId(), "Expected returned audit log to match created audit log.");
  862. }
  863. public function testIsPrimaryKeyNull()
  864. {
  865. $b = new Book();
  866. $this->assertTrue($b->isPrimaryKeyNull());
  867. $b->setPrimaryKey(123);
  868. $this->assertFalse($b->isPrimaryKeyNull());
  869. $b->setPrimaryKey(null);
  870. $this->assertTrue($b->isPrimaryKeyNull());
  871. }
  872. public function testIsPrimaryKeyNullCompmosite()
  873. {
  874. $b = new BookOpinion();
  875. $this->assertTrue($b->isPrimaryKeyNull());
  876. $b->setPrimaryKey(array(123, 456));
  877. $this->assertFalse($b->isPrimaryKeyNull());
  878. $b->setPrimaryKey(array(123, null));
  879. $this->assertFalse($b->isPrimaryKeyNull());
  880. $b->setPrimaryKey(array(null, 456));
  881. $this->assertFalse($b->isPrimaryKeyNull());
  882. $b->setPrimaryKey(array(null, null));
  883. $this->assertTrue($b->isPrimaryKeyNull());
  884. }
  885. public function testAddToStringDefault()
  886. {
  887. $this->assertTrue(method_exists('Author', '__toString'), 'addPrimaryString() adds a __toString() method even if no column has the primaryString attribute');
  888. $author = new Author();
  889. $author->setFirstName('Leo');
  890. $author->setLastName('Tolstoi');
  891. $expected = <<<EOF
  892. Id: null
  893. FirstName: Leo
  894. LastName: Tolstoi
  895. Email: null
  896. Age: null
  897. EOF;
  898. $this->assertEquals($expected, (string) $author, 'addPrimaryString() adds a __toString() method returning the YAML representation of the object where no column is defined as primaryString');
  899. }
  900. public function testAddToStringPrimaryString()
  901. {
  902. $this->assertTrue(method_exists('Book', '__toString'), 'addPrimaryString() adds a __toString() method if a column has the primaryString attribute');
  903. $book = new Book();
  904. $book->setTitle('foo');
  905. $this->assertEquals('foo', (string) $book, 'addPrimaryString() adds a __toString() method returning the value of the the first column where primaryString is true');
  906. }
  907. public function testPreInsert()
  908. {
  909. $author = new TestAuthor();
  910. $author->setFirstName("bogus");
  911. $author->setLastName("Lastname");
  912. $author->save();
  913. $this->assertEquals('PreInsertedFirstname', $author->getFirstName());
  914. }
  915. public function testPreUpdate()
  916. {
  917. $author = new TestAuthor();
  918. $author->setFirstName("bogus");
  919. $author->setLastName("Lastname");
  920. $author->save();
  921. $author->setNew(false);
  922. $author->save();
  923. $this->assertEquals('PreUpdatedFirstname', $author->getFirstName());
  924. }
  925. public function testPostInsert()
  926. {
  927. $author = new TestAuthor();
  928. $author->setFirstName("bogus");
  929. $author->setLastName("Lastname");
  930. $author->save();
  931. $this->assertEquals('PostInsertedLastName', $author->getLastName());
  932. }
  933. public function testPostUpdate()
  934. {
  935. $author = new TestAuthor();
  936. $author->setFirstName("bogus");
  937. $author->setLastName("Lastname");
  938. $author->save();
  939. $author->setNew(false);
  940. $author->save();
  941. $this->assertEquals('PostUpdatedLastName', $author->getLastName());
  942. }
  943. public function testPreSave()
  944. {
  945. $author = new TestAuthor();
  946. $author->setFirstName("bogus");
  947. $author->setLastName("Lastname");
  948. $author->save();
  949. $this->assertEquals('pre@save.com', $author->getEmail());
  950. }
  951. public function testPreSaveFalse()
  952. {
  953. $con = Propel::getConnection(AuthorPeer::DATABASE_NAME);
  954. $author = new TestAuthorSaveFalse();
  955. $author->setFirstName("bogus");
  956. $author->setLastName("Lastname");
  957. $res = $author->save($con);
  958. $this->assertEquals(0, $res);
  959. $this->assertEquals('pre@save.com', $author->getEmail());
  960. $this->assertNotEquals(115, $author->getAge());
  961. $this->assertTrue($author->isNew());
  962. $this->assertEquals(1, $con->getNestedTransactionCount());
  963. }
  964. public function testPostSave()
  965. {
  966. $author = new TestAuthor();
  967. $author->setFirstName("bogus");
  968. $author->setLastName("Lastname");
  969. $author->save();
  970. $this->assertEquals(115, $author->getAge());
  971. }
  972. public function testPreDelete()
  973. {
  974. $author = new TestAuthor();
  975. $author->setFirstName("bogus");
  976. $author->setLastName("Lastname");
  977. $author->save();
  978. $author->delete();
  979. $this->assertEquals("Pre-Deleted", $author->getFirstName());
  980. }
  981. public function testPreDeleteFalse()
  982. {
  983. $con = Propel::getConnection(AuthorPeer::DATABASE_NAME);
  984. $author = new TestAuthorDeleteFalse();
  985. $author->setFirstName("bogus");
  986. $author->setLastName("Lastname");
  987. $author->save($con);
  988. $author->delete($con);
  989. $this->assertEquals("Pre-Deleted", $author->getFirstName());
  990. $this->assertNotEquals("Post-Deleted", $author->getLastName());
  991. $this->assertFalse($author->isDeleted());
  992. $this->assertEquals(1, $con->getNestedTransactionCount());
  993. }
  994. public function testPostDelete()
  995. {
  996. $author = new TestAuthor();
  997. $author->setFirstName("bogus");
  998. $author->setLastName("Lastname");
  999. $author->save();
  1000. $author->delete();
  1001. $this->assertEquals("Post-Deleted", $author->getLastName());
  1002. }
  1003. public function testPostHydrate()
  1004. {
  1005. $author = new TestAuthor();
  1006. $author->hydrate(array(1, 'bogus', 'Lastname', 'bogus@mail.com', 21));
  1007. $this->assertEquals("Post-Hydrated", $author->getLastName());
  1008. }
  1009. public function testMagicVirtualColumnGetter()
  1010. {
  1011. $book = new Book();
  1012. $book->setVirtualColumn('Foo', 'bar');
  1013. $this->assertEquals('bar', $book->getFoo(), 'generated __call() catches getters for virtual columns');
  1014. $book = new Book();
  1015. $book->setVirtualColumn('foo', 'bar');
  1016. $this->assertEquals('bar', $book->getFoo(), 'generated __call() catches getters for virtual columns starting with a lowercase character');
  1017. }
  1018. /**
  1019. * @expectedException PropelException
  1020. */
  1021. public function testMagicCallUndefined()
  1022. {
  1023. $book = new Book();
  1024. $book->fooMethodName();
  1025. }
  1026. public static function conditionsForTestReadOnly()
  1027. {
  1028. return array(
  1029. array('reload'),
  1030. array('delete'),
  1031. array('save'),
  1032. array('doSave'),
  1033. );
  1034. }
  1035. /**
  1036. * @dataProvider conditionsForTestReadOnly
  1037. */
  1038. public function testReadOnly($method)
  1039. {
  1040. $cv = new ContestView();
  1041. $this->assertFalse(method_exists($cv, $method), 'readOnly tables end up with no ' . $method . ' method in the generated object class');
  1042. }
  1043. public function testSetterOneToMany()
  1044. {
  1045. // Ensure no data
  1046. BookQuery::create()->deleteAll();
  1047. AuthorQuery::create()->deleteAll();
  1048. $coll = new PropelObjectCollection();
  1049. $coll->setModel('Book');
  1050. for ($i = 0; $i < 3; $i++) {
  1051. $b = new Book();
  1052. $b->setTitle('Title ' . $i);
  1053. $b->setIsbn('1204' . $i);
  1054. $coll[] = $b;
  1055. }
  1056. $this->assertEquals(3, $coll->count());
  1057. $a = new Author();
  1058. $a->setFirstName('Foo');
  1059. $a->setLastName('Bar');
  1060. $a->setBooks($coll);
  1061. $a->save();
  1062. $this->assertInstanceOf('PropelObjectCollection', $a->getBooks());
  1063. $this->assertEquals(3, $a->getBooks()->count());
  1064. $this->assertEquals(1, AuthorQuery::create()->count());
  1065. $this->assertEquals(3, BookQuery::create()->count());
  1066. $coll->shift();
  1067. $this->assertEquals(2, $coll->count());
  1068. $a->setBooks($coll);
  1069. $a->save();
  1070. $this->assertEquals(2, $a->getBooks()->count());
  1071. $this->assertEquals(1, AuthorQuery::create()->count());
  1072. //The book is not deleted because his fk is not required
  1073. $this->assertEquals(3, BookQuery::create()->count());
  1074. $newBook = new Book();
  1075. $newBook->setTitle('My New Book');
  1076. $newBook->setIsbn(1234);
  1077. // Kind of new collection
  1078. $coll = clone $coll;
  1079. $coll[] = $newBook;
  1080. $a->setBooks($coll);
  1081. $a->save();
  1082. $this->assertEquals(3, $coll->count());
  1083. $this->assertEquals(3, $a->getBooks()->count());
  1084. $this->assertEquals(1, AuthorQuery::create()->count());
  1085. $this->assertEquals(4, BookQuery::create()->count());
  1086. // Add a new object
  1087. $newBook1 = new Book();
  1088. $newBook1->setTitle('My New Book1');
  1089. $newBook1->setIsbn(1256);
  1090. // Existing collection - The fix around reference is tested here.
  1091. $coll[] = $newBook1;
  1092. $a->setBooks($coll);
  1093. $a->save();
  1094. $this->assertEquals(4, $coll->count());
  1095. $this->assertEquals(4, $a->getBooks()->count());
  1096. $this->assertEquals(1, AuthorQuery::create()->count());
  1097. $this->assertEquals(5, BookQuery::create()->count());
  1098. // Add the same collection
  1099. $books = $a->getBooks();
  1100. $a->setBooks($books);
  1101. $a->save();
  1102. $this->assertEquals(4, $books->count());
  1103. $this->assertEquals(4, $a->getBooks()->count());
  1104. $this->assertEquals(1, AuthorQuery::create()->count());
  1105. $this->assertEquals(5, BookQuery::create()->count());
  1106. }
  1107. public function testSetterOneToManyWithFkRequired()
  1108. {
  1109. // Ensure no data
  1110. BookSummaryQuery::create()->deleteAll();
  1111. BookQuery::create()->deleteAll();
  1112. $coll = new PropelObjectCollection();
  1113. $coll->setModel('BookSummary');
  1114. for ($i = 0; $i < 3; $i++) {
  1115. $bs = new BookSummary();
  1116. $bs->setSummary('A summary ' . $i);
  1117. $coll[] = $bs;
  1118. }
  1119. $this->assertEquals(3, $coll->count());
  1120. $b = new Book();
  1121. $b->setTitle('myBook');
  1122. $b->setBookSummarys($coll);
  1123. $b->setIsbn('12242');
  1124. $b->save();
  1125. $this->assertInstanceOf('PropelObjectCollection', $b->getBookSummarys());
  1126. $this->assertEquals(3, $b->getBookSummarys()->count());
  1127. $this->assertEquals(1, BookQuery::create()->count());
  1128. $this->assertEquals(3, BookSummaryQuery::create()->count());
  1129. $coll->shift();
  1130. $this->assertEquals(2, $coll->count());
  1131. $b->setBookSummarys($coll);
  1132. $b->save();
  1133. $this->assertEquals(2, $b->getBookSummarys()->count());
  1134. $this->assertEquals(1, BookQuery::create()->count());
  1135. $this->assertEquals(2, BookSummaryQuery::create()->count());
  1136. $newBookSammary = new BookSummary();
  1137. $newBookSammary->setSummary('My sammary');
  1138. // Kind of new collection
  1139. $coll = clone $coll;
  1140. $coll[] = $newBookSammary;
  1141. $b->setBookSummarys($coll);
  1142. $b->save();
  1143. $this->assertEquals(3, $coll->count());
  1144. $this->assertEquals(3, $b->getBookSummarys()->count());
  1145. $this->assertEquals(1, BookQuery::create()->count());
  1146. $this->assertEquals(3, BookSummaryQuery::create()->count());
  1147. // Add a new object
  1148. $newBookSammary1 = new BookSummary();
  1149. $newBookSammary1->setSummary('My sammary 1');
  1150. // Existing collection - The fix around reference is tested here.
  1151. $coll[] = $newBookSammary1;
  1152. $b->setBookSummarys($coll);
  1153. $b->save();
  1154. $this->assertEquals(4, $coll->count());
  1155. $this->assertEquals(4, $b->getBookSummarys()->count());
  1156. $this->assertEquals(1, BookQuery::create()->count());
  1157. $this->assertEquals(4, BookSummaryQuery::create()->count());
  1158. // Add the same collection
  1159. $bookSummaries = $b->getBookSummarys();
  1160. $b->setBookSummarys($bookSummaries);
  1161. $b->save();
  1162. $this->assertEquals(4, $coll->count());
  1163. $this->assertEquals(4, $b->getBookSummarys()->count());
  1164. $this->assertEquals(1, BookQuery::create()->count());
  1165. $this->assertEquals(4, BookSummaryQuery::create()->count());
  1166. }
  1167. public function testSetterOneToManyWithNoData()
  1168. {
  1169. // Ensure no data
  1170. BookQuery::create()->deleteAll();
  1171. AuthorQuery::create()->deleteAll();
  1172. $books = new PropelObjectCollection();
  1173. $this->assertEquals(0, $books->count());
  1174. // Basic usage
  1175. $a = new Author();
  1176. $a->setFirstName('Foo');
  1177. $a->setLastName('Bar');
  1178. $a->setBooks($books);
  1179. $a->save();
  1180. $this->assertEquals(0, $a->getBooks()->count());
  1181. $this->assertEquals(1, AuthorQuery::create()->count());
  1182. $this->assertEquals(0, BookQuery::create()->count());
  1183. }
  1184. public function testSetterOneToManySavesForeignObjects()
  1185. {
  1186. // Ensure no data
  1187. BookQuery::create()->deleteAll();
  1188. AuthorQuery::create()->deleteAll();
  1189. $book = new Book();
  1190. $book->setTitle('My Book');
  1191. $book->setIsbn('1245');
  1192. $book->save();
  1193. // Modify it but don't save it
  1194. $book->setTitle('My Title');
  1195. $coll = new PropelObjectCollection();
  1196. $coll[] = $book;

Large files files are truncated, but you can click here to view the full file