WorkflowTest.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?php
  2. namespace Ddeboer\DataImport\Tests;
  3. use Ddeboer\DataImport\Exception\WriterException;
  4. use Ddeboer\DataImport\Reader\ArrayReader;
  5. use Ddeboer\DataImport\Step\ConverterStep;
  6. use Ddeboer\DataImport\Step\FilterStep;
  7. use Ddeboer\DataImport\Step\MappingStep;
  8. use Ddeboer\DataImport\Step\ValueConverterStep;
  9. use Ddeboer\DataImport\Writer\ArrayWriter;
  10. use Ddeboer\DataImport\Workflow\StepAggregator;
  11. use Ddeboer\DataImport\Filter\CallbackFilter;
  12. use Ddeboer\DataImport\ValueConverter\CallbackValueConverter;
  13. use Ddeboer\DataImport\ItemConverter\CallbackItemConverter;
  14. use Ddeboer\DataImport\Writer\CallbackWriter;
  15. use Ddeboer\DataImport\Exception\SourceNotFoundException;
  16. class WorkflowTest extends \PHPUnit_Framework_TestCase
  17. {
  18. public function testAddStep()
  19. {
  20. $step = $this->getMock('Ddeboer\DataImport\Step');
  21. $this->getWorkflow()->addStep($step);
  22. }
  23. public function testAddCallbackWriter()
  24. {
  25. $this->getWorkflow()->addWriter(new CallbackWriter(function($item) {
  26. // var_dump($item);
  27. }));
  28. }
  29. public function testWriterIsPreparedAndFinished()
  30. {
  31. $writer = $this->getMockBuilder('\Ddeboer\DataImport\Writer\CallbackWriter')
  32. ->disableOriginalConstructor()
  33. ->getMock();
  34. $writer->expects($this->once())
  35. ->method('prepare');
  36. $writer->expects($this->once())
  37. ->method('finish');
  38. $this->getWorkflow()->addWriter($writer)
  39. ->process();
  40. }
  41. public function testWorkflowWithObjects()
  42. {
  43. $reader = new ArrayReader(array(
  44. new Dummy('foo'),
  45. new Dummy('bar'),
  46. new Dummy('foobar'),
  47. ));
  48. $data = array();
  49. $writer = new ArrayWriter($data);
  50. $workflow = new StepAggregator($reader);
  51. $workflow->addWriter($writer);
  52. $converterStep = new ConverterStep([
  53. function($item) { return array('name' => $item->name); }
  54. ]);
  55. $valueStep = new ValueConverterStep();
  56. $valueStep->add('[name]', function($name) { return strrev($name); });
  57. $workflow->addStep($converterStep)->addStep($valueStep);
  58. $workflow->process();
  59. $this->assertEquals(array(
  60. array('name' => 'oof'),
  61. array('name' => 'rab'),
  62. array('name' => 'raboof')
  63. ), $data);
  64. }
  65. /**
  66. * @expectedException \Ddeboer\DataImport\Exception\UnexpectedTypeException
  67. */
  68. public function testItemConverterWhichReturnObjects()
  69. {
  70. $reader = new ArrayReader(array(
  71. new Dummy('foo'),
  72. new Dummy('bar'),
  73. new Dummy('foobar'),
  74. ));
  75. $data = array();
  76. $writer = new ArrayWriter($data);
  77. $workflow = new StepAggregator($reader);
  78. $workflow->addWriter($writer);
  79. $converterStep = new ConverterStep();
  80. $converterStep->add(function($item) { return $item; });
  81. $workflow->addStep($converterStep)->process();
  82. }
  83. /**
  84. * @expectedException \Ddeboer\DataImport\Exception\UnexpectedTypeException
  85. */
  86. public function testItemConverterWithObjectsAndNoItemConverters()
  87. {
  88. $reader = new ArrayReader(array(
  89. new Dummy('foo'),
  90. new Dummy('bar'),
  91. new Dummy('foobar'),
  92. ));
  93. $data = array();
  94. $writer = new ArrayWriter($data);
  95. $workflow = new StepAggregator($reader);
  96. $workflow->addWriter($writer);
  97. $workflow->process();
  98. }
  99. public function testFilterPriority()
  100. {
  101. $offsetFilter = $this->getMockBuilder('\Ddeboer\DataImport\Filter\OffsetFilter')
  102. ->disableOriginalConstructor()
  103. ->setMethods(array('__invoke'))
  104. ->getMock();
  105. $offsetFilter->expects($this->never())->method('filter');
  106. $validatorFilter = $this->getMockBuilder('\Ddeboer\DataImport\Filter\ValidatorFilter')
  107. ->disableOriginalConstructor()
  108. ->setMethods(array('__invoke'))
  109. ->getMock();
  110. $validatorFilter->expects($this->exactly(3))
  111. ->method('__invoke')
  112. ->will($this->returnValue(false));
  113. $filterStep = (new FilterStep())
  114. ->add($offsetFilter)
  115. ->add($validatorFilter);
  116. $this->getWorkflow()
  117. ->addStep($filterStep)
  118. ->process();
  119. }
  120. public function testFilterPriorityOverride()
  121. {
  122. $offsetFilter = $this->getMockBuilder('\Ddeboer\DataImport\Filter\OffsetFilter')
  123. ->disableOriginalConstructor()
  124. ->setMethods(array('__invoke'))
  125. ->getMock();
  126. $offsetFilter->expects($this->exactly(3))
  127. ->method('__invoke')
  128. ->will($this->returnValue(false));
  129. $validatorFilter = $this->getMockBuilder('\Ddeboer\DataImport\Filter\ValidatorFilter')
  130. ->disableOriginalConstructor()
  131. ->setMethods(array('__invoke'))
  132. ->getMock();
  133. $validatorFilter->expects($this->never())->method('filter');
  134. $filterStep = (new FilterStep())
  135. ->add($offsetFilter, 257)
  136. ->add($validatorFilter);
  137. $this->getWorkflow()
  138. ->addStep($filterStep)
  139. ->process();
  140. }
  141. public function testExceptionInterfaceThrownFromWriterIsCaught()
  142. {
  143. $originalData = array(array('foo' => 'bar'));
  144. $reader = new ArrayReader($originalData);
  145. $array = array();
  146. $writer = $this->getMock('Ddeboer\DataImport\Writer\ArrayWriter', array(), array(&$array));
  147. $exception = new SourceNotFoundException("Log me!");
  148. $writer->expects($this->once())
  149. ->method('writeItem')
  150. ->with($originalData[0])
  151. ->will($this->throwException($exception));
  152. $logger = $this->getMock('Psr\Log\LoggerInterface');
  153. $logger->expects($this->once())
  154. ->method('error')
  155. ->with($exception->getMessage());
  156. $workflow = new StepAggregator($reader);
  157. $workflow->setLogger($logger);
  158. $workflow->setSkipItemOnFailure(true);
  159. $workflow->addWriter($writer);
  160. $workflow->process();
  161. }
  162. public function testWorkflowResultWhenAllSuccessful()
  163. {
  164. $workflow = $this->getWorkflow();
  165. $result = $workflow->process();
  166. $this->assertInstanceOf('Ddeboer\DataImport\Result', $result);
  167. $this->assertInstanceOf('DateTime', $result->getStartTime());
  168. $this->assertInstanceOf('DateTime', $result->getEndTime());
  169. $this->assertInstanceOf('DateInterval', $result->getElapsed());
  170. $this->assertInstanceOf('Ddeboer\DataImport\Result', $result);
  171. $this->assertSame(3, $result->getTotalProcessedCount());
  172. $this->assertSame(3, $result->getSuccessCount());
  173. $this->assertSame(0, $result->getErrorCount());
  174. $this->assertFalse($result->hasErrors());
  175. $this->assertEmpty($result->getExceptions());
  176. $this->assertSame(null, $result->getName());
  177. }
  178. public function testMultipleMappingsForAnItemAfterAnotherItemConverterwasAdded()
  179. {
  180. $originalData = array(array('foo' => 'bar', 'baz' => 'value'));
  181. $outputTestData = array();
  182. $writer = new ArrayWriter($outputTestData);
  183. $reader = new ArrayReader($originalData);
  184. $workflow = new StepAggregator($reader);
  185. $converterStep = new ConverterStep();
  186. // add a dummy item converter
  187. $converterStep->add(function($item) { return $item; });
  188. $mappingStep = (new MappingStep())
  189. ->map('[foo]', '[bar]')
  190. ->map('[baz]', '[bazzoo]');
  191. // add multiple mappings
  192. $workflow
  193. ->addStep($converterStep)
  194. ->addStep($mappingStep)
  195. ->addWriter($writer)
  196. ->process()
  197. ;
  198. $this->assertArrayHasKey('bar', $outputTestData[0]);
  199. $this->assertArrayHasKey('bazzoo', $outputTestData[0]);
  200. }
  201. public function _testWorkflowResultWithExceptionThrowFromWriter()
  202. {
  203. $workflow = $this->getWorkflow();
  204. $workflow->setSkipItemOnFailure(true);
  205. $writer = $this->getMock('Ddeboer\DataImport\Writer\WriterInterface');
  206. $e = new WriterException();
  207. $writer
  208. ->expects($this->at(1))
  209. ->method('writeItem')
  210. ->with(array('first' => 'James', 'last' => 'Bond'))
  211. ->will($this->throwException($e));
  212. $workflow->addWriter($writer);
  213. $result = $workflow->process();
  214. $this->assertInstanceOf('Ddeboer\DataImport\Result', $result);
  215. $this->assertInstanceOf('DateTime', $result->getStartTime());
  216. $this->assertInstanceOf('DateTime', $result->getEndTime());
  217. $this->assertInstanceOf('DateInterval', $result->getElapsed());
  218. $this->assertInstanceOf('Ddeboer\DataImport\Result', $result);
  219. $this->assertSame(3, $result->getTotalProcessedCount());
  220. $this->assertSame(2, $result->getSuccessCount());
  221. $this->assertSame(1, $result->getErrorCount());
  222. $this->assertTrue($result->hasErrors());
  223. $this->assertSame(array($e), iterator_to_array($result->getExceptions()));
  224. $this->assertSame(null, $result->getName());
  225. }
  226. protected function getWorkflow()
  227. {
  228. $reader = new ArrayReader(array(
  229. array(
  230. 'first' => 'James',
  231. 'last' => 'Bond'
  232. ),
  233. array(
  234. 'first' => 'Miss',
  235. 'last' => 'Moneypenny'
  236. ),
  237. array(
  238. 'first' => null,
  239. 'last' => 'Doe'
  240. )
  241. ));
  242. return new StepAggregator($reader);
  243. }
  244. }
  245. class Dummy
  246. {
  247. public $name;
  248. public function __construct($name)
  249. {
  250. $this->name = $name;
  251. }
  252. }