FunctionReduceTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <?php
  2. namespace React\Promise;
  3. class FunctionReduceTest extends TestCase
  4. {
  5. protected function plus()
  6. {
  7. return function ($sum, $val) {
  8. return $sum + $val;
  9. };
  10. }
  11. protected function append()
  12. {
  13. return function ($sum, $val) {
  14. return $sum . $val;
  15. };
  16. }
  17. /** @test */
  18. public function shouldReduceValuesWithoutInitialValue()
  19. {
  20. $mock = $this->createCallableMock();
  21. $mock
  22. ->expects($this->once())
  23. ->method('__invoke')
  24. ->with($this->identicalTo(6));
  25. reduce(
  26. [1, 2, 3],
  27. $this->plus()
  28. )->then($mock);
  29. }
  30. /** @test */
  31. public function shouldReduceValuesWithInitialValue()
  32. {
  33. $mock = $this->createCallableMock();
  34. $mock
  35. ->expects($this->once())
  36. ->method('__invoke')
  37. ->with($this->identicalTo(7));
  38. reduce(
  39. [1, 2, 3],
  40. $this->plus(),
  41. 1
  42. )->then($mock);
  43. }
  44. /** @test */
  45. public function shouldReduceValuesWithInitialPromise()
  46. {
  47. $mock = $this->createCallableMock();
  48. $mock
  49. ->expects($this->once())
  50. ->method('__invoke')
  51. ->with($this->identicalTo(7));
  52. reduce(
  53. [1, 2, 3],
  54. $this->plus(),
  55. resolve(1)
  56. )->then($mock);
  57. }
  58. /** @test */
  59. public function shouldReducePromisedValuesWithoutInitialValue()
  60. {
  61. $mock = $this->createCallableMock();
  62. $mock
  63. ->expects($this->once())
  64. ->method('__invoke')
  65. ->with($this->identicalTo(6));
  66. reduce(
  67. [resolve(1), resolve(2), resolve(3)],
  68. $this->plus()
  69. )->then($mock);
  70. }
  71. /** @test */
  72. public function shouldReducePromisedValuesWithInitialValue()
  73. {
  74. $mock = $this->createCallableMock();
  75. $mock
  76. ->expects($this->once())
  77. ->method('__invoke')
  78. ->with($this->identicalTo(7));
  79. reduce(
  80. [resolve(1), resolve(2), resolve(3)],
  81. $this->plus(),
  82. 1
  83. )->then($mock);
  84. }
  85. /** @test */
  86. public function shouldReducePromisedValuesWithInitialPromise()
  87. {
  88. $mock = $this->createCallableMock();
  89. $mock
  90. ->expects($this->once())
  91. ->method('__invoke')
  92. ->with($this->identicalTo(7));
  93. reduce(
  94. [resolve(1), resolve(2), resolve(3)],
  95. $this->plus(),
  96. resolve(1)
  97. )->then($mock);
  98. }
  99. /** @test */
  100. public function shouldReduceEmptyInputWithInitialValue()
  101. {
  102. $mock = $this->createCallableMock();
  103. $mock
  104. ->expects($this->once())
  105. ->method('__invoke')
  106. ->with($this->identicalTo(1));
  107. reduce(
  108. [],
  109. $this->plus(),
  110. 1
  111. )->then($mock);
  112. }
  113. /** @test */
  114. public function shouldReduceEmptyInputWithInitialPromise()
  115. {
  116. $mock = $this->createCallableMock();
  117. $mock
  118. ->expects($this->once())
  119. ->method('__invoke')
  120. ->with($this->identicalTo(1));
  121. reduce(
  122. [],
  123. $this->plus(),
  124. resolve(1)
  125. )->then($mock);
  126. }
  127. /** @test */
  128. public function shouldRejectWhenInputContainsRejection()
  129. {
  130. $mock = $this->createCallableMock();
  131. $mock
  132. ->expects($this->once())
  133. ->method('__invoke')
  134. ->with($this->identicalTo(2));
  135. reduce(
  136. [resolve(1), reject(2), resolve(3)],
  137. $this->plus(),
  138. resolve(1)
  139. )->then($this->expectCallableNever(), $mock);
  140. }
  141. /** @test */
  142. public function shouldResolveWithNullWhenInputIsEmptyAndNoInitialValueOrPromiseProvided()
  143. {
  144. // Note: this is different from when.js's behavior!
  145. // In when.reduce(), this rejects with a TypeError exception (following
  146. // JavaScript's [].reduce behavior.
  147. // We're following PHP's array_reduce behavior and resolve with NULL.
  148. $mock = $this->createCallableMock();
  149. $mock
  150. ->expects($this->once())
  151. ->method('__invoke')
  152. ->with($this->identicalTo(null));
  153. reduce(
  154. [],
  155. $this->plus()
  156. )->then($mock);
  157. }
  158. /** @test */
  159. public function shouldAllowSparseArrayInputWithoutInitialValue()
  160. {
  161. $mock = $this->createCallableMock();
  162. $mock
  163. ->expects($this->once())
  164. ->method('__invoke')
  165. ->with($this->identicalTo(3));
  166. reduce(
  167. [null, null, 1, null, 1, 1],
  168. $this->plus()
  169. )->then($mock);
  170. }
  171. /** @test */
  172. public function shouldAllowSparseArrayInputWithInitialValue()
  173. {
  174. $mock = $this->createCallableMock();
  175. $mock
  176. ->expects($this->once())
  177. ->method('__invoke')
  178. ->with($this->identicalTo(4));
  179. reduce(
  180. [null, null, 1, null, 1, 1],
  181. $this->plus(),
  182. 1
  183. )->then($mock);
  184. }
  185. /** @test */
  186. public function shouldReduceInInputOrder()
  187. {
  188. $mock = $this->createCallableMock();
  189. $mock
  190. ->expects($this->once())
  191. ->method('__invoke')
  192. ->with($this->identicalTo('123'));
  193. reduce(
  194. [1, 2, 3],
  195. $this->append(),
  196. ''
  197. )->then($mock);
  198. }
  199. /** @test */
  200. public function shouldAcceptAPromiseForAnArray()
  201. {
  202. $mock = $this->createCallableMock();
  203. $mock
  204. ->expects($this->once())
  205. ->method('__invoke')
  206. ->with($this->identicalTo('123'));
  207. reduce(
  208. resolve([1, 2, 3]),
  209. $this->append(),
  210. ''
  211. )->then($mock);
  212. }
  213. /** @test */
  214. public function shouldResolveToInitialValueWhenInputPromiseDoesNotResolveToAnArray()
  215. {
  216. $mock = $this->createCallableMock();
  217. $mock
  218. ->expects($this->once())
  219. ->method('__invoke')
  220. ->with($this->identicalTo(1));
  221. reduce(
  222. resolve(1),
  223. $this->plus(),
  224. 1
  225. )->then($mock);
  226. }
  227. /** @test */
  228. public function shouldProvideCorrectBasisValue()
  229. {
  230. $insertIntoArray = function ($arr, $val, $i) {
  231. $arr[$i] = $val;
  232. return $arr;
  233. };
  234. $d1 = new Deferred();
  235. $d2 = new Deferred();
  236. $d3 = new Deferred();
  237. $mock = $this->createCallableMock();
  238. $mock
  239. ->expects($this->once())
  240. ->method('__invoke')
  241. ->with($this->identicalTo([1, 2, 3]));
  242. reduce(
  243. [$d1->promise(), $d2->promise(), $d3->promise()],
  244. $insertIntoArray,
  245. []
  246. )->then($mock);
  247. $d3->resolve(3);
  248. $d1->resolve(1);
  249. $d2->resolve(2);
  250. }
  251. /** @test */
  252. public function shouldRejectWhenInputPromiseRejects()
  253. {
  254. $mock = $this->createCallableMock();
  255. $mock
  256. ->expects($this->once())
  257. ->method('__invoke')
  258. ->with($this->identicalTo(null));
  259. reduce(
  260. reject(),
  261. $this->plus(),
  262. 1
  263. )->then($this->expectCallableNever(), $mock);
  264. }
  265. /** @test */
  266. public function shouldCancelInputPromise()
  267. {
  268. $mock = $this
  269. ->getMockBuilder('React\Promise\CancellablePromiseInterface')
  270. ->getMock();
  271. $mock
  272. ->expects($this->once())
  273. ->method('cancel');
  274. reduce(
  275. $mock,
  276. $this->plus(),
  277. 1
  278. )->cancel();
  279. }
  280. /** @test */
  281. public function shouldCancelInputArrayPromises()
  282. {
  283. $mock1 = $this
  284. ->getMockBuilder('React\Promise\CancellablePromiseInterface')
  285. ->getMock();
  286. $mock1
  287. ->expects($this->once())
  288. ->method('cancel');
  289. $mock2 = $this
  290. ->getMockBuilder('React\Promise\CancellablePromiseInterface')
  291. ->getMock();
  292. $mock2
  293. ->expects($this->once())
  294. ->method('cancel');
  295. reduce(
  296. [$mock1, $mock2],
  297. $this->plus(),
  298. 1
  299. )->cancel();
  300. }
  301. }