MultiDimensionProviderTest.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\Framework\Indexer\Test\Unit;
  8. use \Magento\Framework\Indexer\MultiDimensionProvider;
  9. use \Magento\Framework\Indexer\DimensionProviderInterface;
  10. use \Magento\Framework\Indexer\Dimension;
  11. class MultiDimensionProviderTest extends \PHPUnit\Framework\TestCase
  12. {
  13. /**
  14. * tests that MultiDimensionProvider will return [[]] in case it has no dimension providers
  15. */
  16. public function testWithNoDataProviders()
  17. {
  18. // prepare expected dimensions
  19. $expectedDimensions = [[]];
  20. // collect actual dimensions
  21. $multiDimensionProvider = new MultiDimensionProvider([]);
  22. $actualDimensions = [];
  23. foreach ($multiDimensionProvider as $dimension) {
  24. $actualDimensions[] = $dimension;
  25. }
  26. $this->assertSame($expectedDimensions, $actualDimensions);
  27. }
  28. /**
  29. * tests multiplication of dimensions from different providers
  30. *
  31. * e.g we have three dimensions:
  32. * - dimension X with values (x1, x2)
  33. * - dimension Y with values (y1, y2, y3)
  34. * - dimension Z with values (z1, z2)
  35. *
  36. * the multiplication result set will be:
  37. * x1-y1-z1
  38. * x1-y1-z2
  39. * x1-y2-z1
  40. * x1-y2-z2
  41. * x1-y3-z1
  42. * x1-y3-z2
  43. * x2-y1-z1
  44. * x2-y1-z2
  45. * x2-y2-z1
  46. * x2-y2-z2
  47. * x2-y3-z1
  48. * x2-y3-z2
  49. */
  50. public function testWithMultipleDataProviders()
  51. {
  52. // prepare expected dimensions
  53. $dimensionXData = [
  54. $this->getDimensionMock('x', '1'),
  55. $this->getDimensionMock('x', '2'),
  56. $this->getDimensionMock('x', '3'),
  57. ];
  58. $dimensionYData = [
  59. $this->getDimensionMock('y', '1'),
  60. $this->getDimensionMock('y', '2'),
  61. $this->getDimensionMock('y', '3'),
  62. $this->getDimensionMock('y', '4'),
  63. $this->getDimensionMock('y', '5'),
  64. ];
  65. $dimensionZData = [
  66. $this->getDimensionMock('z', '1'),
  67. $this->getDimensionMock('z', '2'),
  68. ];
  69. $expectedDimensions = [];
  70. foreach ($dimensionXData as $dimensionX) {
  71. foreach ($dimensionYData as $dimensionY) {
  72. foreach ($dimensionZData as $dimensionZ) {
  73. $expectedDimensions[] = [
  74. $dimensionX->getName() => $dimensionX,
  75. $dimensionY->getName() => $dimensionY,
  76. $dimensionZ->getName() => $dimensionZ,
  77. ];
  78. }
  79. }
  80. }
  81. // collect actual dimensions
  82. $multiDimensionProvider = new MultiDimensionProvider(
  83. [
  84. $this->getDimensionProviderMock($dimensionXData),
  85. $this->getDimensionProviderMock($dimensionYData),
  86. $this->getDimensionProviderMock($dimensionZData),
  87. ]
  88. );
  89. $actualDimensions = [];
  90. foreach ($multiDimensionProvider as $dimension) {
  91. $actualDimensions[] = $dimension;
  92. }
  93. $this->assertSame($expectedDimensions, $actualDimensions);
  94. }
  95. /**
  96. * tests that the same MultiDimensionProvider can be used in foreach multiple times without creating again
  97. */
  98. public function testMultiDimensionProviderIsReIterable()
  99. {
  100. // prepare expected dimensions
  101. $dimensionXData = [
  102. $this->getDimensionMock('x', '1'),
  103. $this->getDimensionMock('x', '2'),
  104. $this->getDimensionMock('x', '3'),
  105. ];
  106. $dimensionZData = [
  107. $this->getDimensionMock('z', '1'),
  108. $this->getDimensionMock('z', '2'),
  109. ];
  110. // collect actual dimensions
  111. $multiDimensionProvider = new MultiDimensionProvider(
  112. [
  113. $this->getDimensionProviderMock($dimensionXData),
  114. $this->getDimensionProviderMock($dimensionZData),
  115. ]
  116. );
  117. // first iteration
  118. $actualDimensions1st = [];
  119. foreach ($multiDimensionProvider as $dimension) {
  120. $actualDimensions1st[] = $dimension;
  121. }
  122. // second iteration
  123. $actualDimensions2nd = [];
  124. foreach ($multiDimensionProvider as $dimension) {
  125. $actualDimensions2nd[] = $dimension;
  126. }
  127. $this->assertSame($actualDimensions1st, $actualDimensions2nd);
  128. }
  129. /**
  130. * tests that MultiDimensionProvider will throw exception when all dimension providers has nothing to return
  131. *
  132. * @expectedException \LogicException
  133. * @expectedExceptionMessage Can`t multiple dimensions because some of them are empty.
  134. */
  135. public function testMultiDimensionProviderWithEmptyDataProvider()
  136. {
  137. // collect actual dimensions
  138. $multiDimensionProvider = new MultiDimensionProvider(
  139. [
  140. $this->getDimensionProviderMock([]),
  141. $this->getDimensionProviderMock([]),
  142. ]
  143. );
  144. $actualDimensions = [];
  145. foreach ($multiDimensionProvider as $dimension) {
  146. $actualDimensions[] = $dimension;
  147. }
  148. }
  149. /**
  150. * tests that MultiDimensionProvider will throw exception when one dimension providers has nothing to return
  151. *
  152. * @expectedException \LogicException
  153. * @expectedExceptionMessage Can`t multiple dimensions because some of them are empty.
  154. */
  155. public function testMultiDimensionProviderWithMixedDataProvider()
  156. {
  157. // prepare expected dimensions
  158. $dimensionXData = [
  159. $this->getDimensionMock('x', '1'),
  160. $this->getDimensionMock('x', '2'),
  161. $this->getDimensionMock('x', '3'),
  162. ];
  163. $dimensionYData = [
  164. $this->getDimensionMock('y', '1'),
  165. $this->getDimensionMock('y', '2'),
  166. $this->getDimensionMock('y', '3'),
  167. $this->getDimensionMock('y', '4'),
  168. $this->getDimensionMock('y', '5'),
  169. ];
  170. $dimensionZData = [];
  171. // collect actual dimensions
  172. $multiDimensionProvider = new MultiDimensionProvider(
  173. [
  174. $this->getDimensionProviderMock($dimensionXData),
  175. $this->getDimensionProviderMock($dimensionYData),
  176. $this->getDimensionProviderMock($dimensionZData),
  177. ]
  178. );
  179. $actualDimensions = [];
  180. foreach ($multiDimensionProvider as $dimension) {
  181. $actualDimensions[] = $dimension;
  182. }
  183. }
  184. private function getDimensionProviderMock($dimensions)
  185. {
  186. $dimensionProviderMock = $this->getMockBuilder(DimensionProviderInterface::class)
  187. ->disableOriginalConstructor()
  188. ->disableOriginalClone()
  189. ->disableArgumentCloning()
  190. ->disallowMockingUnknownTypes()
  191. ->setMethods(['getIterator'])
  192. ->getMockForAbstractClass();
  193. $dimensionProviderMock->expects($this->any())
  194. ->method('getIterator')
  195. ->will(
  196. $this->returnCallback(
  197. function () use ($dimensions) {
  198. return \SplFixedArray::fromArray($dimensions);
  199. }
  200. )
  201. );
  202. return $dimensionProviderMock;
  203. }
  204. private function getDimensionMock(string $name, string $value)
  205. {
  206. $dimensionMock = $this->getMockBuilder(Dimension::class)
  207. ->disableOriginalConstructor()
  208. ->disableOriginalClone()
  209. ->disableArgumentCloning()
  210. ->disallowMockingUnknownTypes()
  211. ->setMethods(['getName', 'getValue'])
  212. ->getMock();
  213. $dimensionMock->expects($this->any())
  214. ->method('getName')
  215. ->willReturn($name);
  216. $dimensionMock->expects($this->any())
  217. ->method('getValue')
  218. ->willReturn($value);
  219. return $dimensionMock;
  220. }
  221. }