RepositoryTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. <?php
  2. namespace Gedmo\Tree;
  3. use Doctrine\Common\EventManager;
  4. use Tool\BaseTestCaseORM;
  5. use Doctrine\Common\Util\Debug,
  6. Tree\Fixture\Category;
  7. /**
  8. * These are tests for Tree behavior
  9. *
  10. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  11. * @package Gedmo.Tree
  12. * @link http://www.gediminasm.org
  13. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  14. */
  15. class RepositoryTest extends BaseTestCaseORM
  16. {
  17. const CATEGORY = "Tree\\Fixture\\Category";
  18. protected function setUp()
  19. {
  20. parent::setUp();
  21. $evm = new EventManager;
  22. $evm->addEventSubscriber(new TreeListener);
  23. $this->getMockSqliteEntityManager($evm);
  24. $this->populate();
  25. }
  26. public function testBasicFunctions()
  27. {
  28. $vegies = $this->em->getRepository(self::CATEGORY)
  29. ->findOneByTitle('Vegitables');
  30. $food = $this->em->getRepository(self::CATEGORY)
  31. ->findOneByTitle('Food');
  32. // test childCount
  33. $childCount = $this->em->getRepository(self::CATEGORY)
  34. ->childCount($vegies);
  35. $this->assertEquals(2, $childCount);
  36. $childCount = $this->em->getRepository(self::CATEGORY)
  37. ->childCount($food);
  38. $this->assertEquals(4, $childCount);
  39. $childCount = $this->em->getRepository(self::CATEGORY)
  40. ->childCount($food, true);
  41. $this->assertEquals(2, $childCount);
  42. $childCount = $this->em->getRepository(self::CATEGORY)
  43. ->childCount();
  44. $this->assertEquals(6, $childCount);
  45. // test children
  46. $children = $this->em->getRepository(self::CATEGORY)
  47. ->children($vegies);
  48. $this->assertEquals(2, count($children));
  49. $this->assertEquals('Carrots', $children[0]->getTitle());
  50. $this->assertEquals('Potatoes', $children[1]->getTitle());
  51. $children = $this->em->getRepository(self::CATEGORY)
  52. ->children($food);
  53. $this->assertEquals(4, count($children));
  54. $this->assertEquals('Fruits', $children[0]->getTitle());
  55. $this->assertEquals('Vegitables', $children[1]->getTitle());
  56. $this->assertEquals('Carrots', $children[2]->getTitle());
  57. $this->assertEquals('Potatoes', $children[3]->getTitle());
  58. $children = $this->em->getRepository(self::CATEGORY)
  59. ->children($food, true);
  60. $this->assertEquals(2, count($children));
  61. $this->assertEquals('Fruits', $children[0]->getTitle());
  62. $this->assertEquals('Vegitables', $children[1]->getTitle());
  63. $children = $this->em->getRepository(self::CATEGORY)
  64. ->children();
  65. $this->assertEquals(6, count($children));
  66. // path
  67. $path = $this->em->getRepository(self::CATEGORY)
  68. ->getPath($vegies);
  69. $this->assertEquals(2, count($path));
  70. $this->assertEquals('Food', $path[0]->getTitle());
  71. $this->assertEquals('Vegitables', $path[1]->getTitle());
  72. $carrots = $this->em->getRepository(self::CATEGORY)
  73. ->findOneByTitle('Carrots');
  74. $path = $this->em->getRepository(self::CATEGORY)
  75. ->getPath($carrots);
  76. $this->assertEquals(3, count($path));
  77. $this->assertEquals('Food', $path[0]->getTitle());
  78. $this->assertEquals('Vegitables', $path[1]->getTitle());
  79. $this->assertEquals('Carrots', $path[2]->getTitle());
  80. // leafs
  81. $leafs = $this->em->getRepository(self::CATEGORY)
  82. ->getLeafs();
  83. $this->assertEquals(4, count($leafs));
  84. $this->assertEquals('Fruits', $leafs[0]->getTitle());
  85. $this->assertEquals('Carrots', $leafs[1]->getTitle());
  86. $this->assertEquals('Potatoes', $leafs[2]->getTitle());
  87. $this->assertEquals('Sports', $leafs[3]->getTitle());
  88. }
  89. public function testAdvancedFunctions()
  90. {
  91. $this->populateMore();
  92. $onions = $this->em->getRepository(self::CATEGORY)
  93. ->findOneByTitle('Onions');
  94. $repo = $this->em->getRepository(self::CATEGORY);
  95. $meta = $this->em->getClassMetadata(self::CATEGORY);
  96. $left = $meta->getReflectionProperty('lft')->getValue($onions);
  97. $right = $meta->getReflectionProperty('rgt')->getValue($onions);
  98. $this->assertEquals($left, 11);
  99. $this->assertEquals($right, 12);
  100. // move up onions by one position
  101. $repo->moveUp($onions, 1);
  102. $left = $meta->getReflectionProperty('lft')->getValue($onions);
  103. $right = $meta->getReflectionProperty('rgt')->getValue($onions);
  104. $this->assertEquals($left, 9);
  105. $this->assertEquals($right, 10);
  106. // move down onions by one position
  107. $repo->moveDown($onions, 1);
  108. $left = $meta->getReflectionProperty('lft')->getValue($onions);
  109. $right = $meta->getReflectionProperty('rgt')->getValue($onions);
  110. $this->assertEquals($left, 11);
  111. $this->assertEquals($right, 12);
  112. // move to the up onions on this level
  113. $repo->moveUp($onions, true);
  114. $left = $meta->getReflectionProperty('lft')->getValue($onions);
  115. $right = $meta->getReflectionProperty('rgt')->getValue($onions);
  116. $this->assertEquals($left, 5);
  117. $this->assertEquals($right, 6);
  118. // test tree reordering
  119. // reorder tree by title
  120. $food = $repo->findOneByTitle('Food');
  121. $repo->reorder($food, 'title');
  122. $node = $this->em->getRepository(self::CATEGORY)
  123. ->findOneByTitle('Cabbages');
  124. $left = $meta->getReflectionProperty('lft')->getValue($node);
  125. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  126. $this->assertEquals($left, 5);
  127. $this->assertEquals($right, 6);
  128. $node = $this->em->getRepository(self::CATEGORY)
  129. ->findOneByTitle('Carrots');
  130. $left = $meta->getReflectionProperty('lft')->getValue($node);
  131. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  132. $this->assertEquals($left, 7);
  133. $this->assertEquals($right, 8);
  134. $node = $this->em->getRepository(self::CATEGORY)
  135. ->findOneByTitle('Onions');
  136. $left = $meta->getReflectionProperty('lft')->getValue($node);
  137. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  138. $this->assertEquals($left, 9);
  139. $this->assertEquals($right, 10);
  140. $node = $this->em->getRepository(self::CATEGORY)
  141. ->findOneByTitle('Potatoes');
  142. $left = $meta->getReflectionProperty('lft')->getValue($node);
  143. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  144. $this->assertEquals($left, 11);
  145. $this->assertEquals($right, 12);
  146. // test removal with reparenting
  147. $vegies = $this->em->getRepository(self::CATEGORY)
  148. ->findOneByTitle('Vegitables');
  149. $repo->removeFromTree($vegies);
  150. $this->em->clear(); // clear all cached nodes
  151. $vegies = $this->em->getRepository(self::CATEGORY)
  152. ->findOneByTitle('Vegitables');
  153. $this->assertTrue($vegies === null);
  154. $node = $this->em->getRepository(self::CATEGORY)
  155. ->findOneByTitle('Fruits');
  156. $left = $meta->getReflectionProperty('lft')->getValue($node);
  157. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  158. $this->assertEquals($left, 2);
  159. $this->assertEquals($right, 3);
  160. $this->assertEquals('Food', $node->getParent()->getTitle());
  161. $node = $this->em->getRepository(self::CATEGORY)
  162. ->findOneByTitle('Cabbages');
  163. $left = $meta->getReflectionProperty('lft')->getValue($node);
  164. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  165. $this->assertEquals($left, 4);
  166. $this->assertEquals($right, 5);
  167. $this->assertEquals('Food', $node->getParent()->getTitle());
  168. }
  169. public function testRootRemoval()
  170. {
  171. $repo = $this->em->getRepository(self::CATEGORY);
  172. $meta = $this->em->getClassMetadata(self::CATEGORY);
  173. $this->populateMore();
  174. $food = $repo->findOneByTitle('Food');
  175. $repo->removeFromTree($food);
  176. $this->em->clear();
  177. $food = $repo->findOneByTitle('Food');
  178. $this->assertTrue(is_null($food));
  179. $node = $repo->findOneByTitle('Fruits');
  180. $left = $meta->getReflectionProperty('lft')->getValue($node);
  181. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  182. $this->assertEquals($left, 1);
  183. $this->assertEquals($right, 2);
  184. $this->assertTrue(is_null($node->getParent()));
  185. $node = $repo->findOneByTitle('Vegitables');
  186. $left = $meta->getReflectionProperty('lft')->getValue($node);
  187. $right = $meta->getReflectionProperty('rgt')->getValue($node);
  188. $this->assertEquals($left, 3);
  189. $this->assertEquals($right, 12);
  190. $this->assertTrue(is_null($node->getParent()));
  191. }
  192. public function testVerificationAndRecover()
  193. {
  194. $repo = $this->em->getRepository(self::CATEGORY);
  195. $meta = $this->em->getClassMetadata(self::CATEGORY);
  196. $this->populateMore();
  197. // test verification of tree
  198. $this->assertTrue($repo->verify());
  199. // now lets brake something
  200. $dql = 'UPDATE ' . self::CATEGORY . ' node';
  201. $dql .= ' SET node.lft = 1';
  202. $dql .= ' WHERE node.id = 8';
  203. $q = $this->em->createQuery($dql);
  204. $q->getSingleScalarResult();
  205. $this->em->clear(); // must clear cached entities
  206. // verify again
  207. $result = $repo->verify();
  208. $this->assertTrue(is_array($result));
  209. $this->assertArrayHasKey(0, $result);
  210. $this->assertArrayHasKey(1, $result);
  211. $this->assertArrayHasKey(2, $result);
  212. $duplicate = $result[0];
  213. $missing = $result[1];
  214. $invalidLeft = $result[2];
  215. $this->assertEquals('index [1], duplicate', $duplicate);
  216. $this->assertEquals('index [11], missing', $missing);
  217. $this->assertEquals('node [8] left is less than parent`s [4] left value', $invalidLeft);
  218. // test recover functionality
  219. // @todo implement
  220. //$repo->recover();
  221. //$this->em->clear(); // must clear cached entities
  222. //$this->assertTrue($repo->verify());
  223. }
  224. public function testMoveRootNode()
  225. {
  226. $repo = $this->em->getRepository(self::CATEGORY);
  227. $food = $repo->findOneByTitle('Food');
  228. $repo->moveDown($food, 1);
  229. $meta = $this->em->getClassMetadata(self::CATEGORY);
  230. $left = $meta->getReflectionProperty('lft')->getValue($food);
  231. $right = $meta->getReflectionProperty('rgt')->getValue($food);
  232. $this->assertEquals($left, 3);
  233. $this->assertEquals($right, 12);
  234. $this->assertEquals(null, $food->getParent());
  235. $this->assertTrue($repo->verify());
  236. }
  237. protected function getUsedEntityFixtures()
  238. {
  239. return array(
  240. self::CATEGORY
  241. );
  242. }
  243. private function populateMore()
  244. {
  245. $vegies = $this->em->getRepository(self::CATEGORY)
  246. ->findOneByTitle('Vegitables');
  247. $cabbages = new Category();
  248. $cabbages->setParent($vegies);
  249. $cabbages->setTitle('Cabbages');
  250. $onions = new Category();
  251. $onions->setParent($vegies);
  252. $onions->setTitle('Onions');
  253. $this->em->persist($cabbages);
  254. $this->em->persist($onions);
  255. $this->em->flush();
  256. $this->em->clear();
  257. }
  258. private function populate()
  259. {
  260. $root = new Category();
  261. $root->setTitle("Food");
  262. $root2 = new Category();
  263. $root2->setTitle("Sports");
  264. $child = new Category();
  265. $child->setTitle("Fruits");
  266. $child->setParent($root);
  267. $child2 = new Category();
  268. $child2->setTitle("Vegitables");
  269. $child2->setParent($root);
  270. $childsChild = new Category();
  271. $childsChild->setTitle("Carrots");
  272. $childsChild->setParent($child2);
  273. $potatoes = new Category();
  274. $potatoes->setTitle("Potatoes");
  275. $potatoes->setParent($child2);
  276. $this->em->persist($root);
  277. $this->em->persist($root2);
  278. $this->em->persist($child);
  279. $this->em->persist($child2);
  280. $this->em->persist($childsChild);
  281. $this->em->persist($potatoes);
  282. $this->em->flush();
  283. $this->em->clear();
  284. }
  285. }