QueueWorkflowTest::testSimpleExport()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 71
c 0
b 0
f 0
rs 8.6327
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Maketok\DataMigration\IntegrationTest;
4
5
use Faker\Generator;
6
use Faker\Provider\Address;
7
use Faker\Provider\Base;
8
use Faker\Provider\Internet;
9
use Faker\Provider\Lorem;
10
use Faker\Provider\Person;
11
use Maketok\DataMigration\Action\ConfigInterface;
12
use Maketok\DataMigration\Action\Type\AssembleInput;
13
use Maketok\DataMigration\Action\Type\CreateTmpFiles;
14
use Maketok\DataMigration\Action\Type\Delete;
15
use Maketok\DataMigration\Action\Type\Dump;
16
use Maketok\DataMigration\Action\Type\Generate;
17
use Maketok\DataMigration\Action\Type\Load;
18
use Maketok\DataMigration\Action\Type\Move;
19
use Maketok\DataMigration\Action\Type\ReverseMove;
20
use Maketok\DataMigration\ArrayMap;
21
use Maketok\DataMigration\Expression\HelperExpressionsProvider;
22
use Maketok\DataMigration\Expression\LanguageAdapter;
23
use Maketok\DataMigration\Hashmap\ArrayHashmap;
24
use Maketok\DataMigration\Input\Csv;
25
use Maketok\DataMigration\Input\Shaper\Processor\Duplicates;
26
use Maketok\DataMigration\Input\Shaper\Processor\Nulls;
27
use Maketok\DataMigration\QueueWorkflow;
28
use Maketok\DataMigration\Storage\Db\DBALMysqlResource;
29
use Maketok\DataMigration\Storage\Db\DBALMysqlResourceHelper;
30
use Maketok\DataMigration\Unit\SimpleBag;
31
use Maketok\DataMigration\Unit\Type\Unit;
32
use Maketok\DataMigration\Workflow\Result;
33
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
34
35
class QueueWorkflowTest extends \PHPUnit_Extensions_Database_TestCase
0 ignored issues
show
Complexity introduced by
The class QueueWorkflowTest has a coupling between objects value of 40. Consider to reduce the number of dependencies under 13.
Loading history...
36
{
37
    /**
38
     * @var ConfigInterface
39
     */
40
    private $config;
41
    /**
42
     * @var DBALMysqlResource
43
     */
44
    private $resource;
45
    /**
46
     * @var \PDO
47
     */
48
    private $pdo;
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    protected function setUp()
54
    {
55
        $config = include __DIR__ . '/Storage/Db/assets/config.php';
56
        if (isset($config) && $config instanceof ConfigInterface) {
57
            $this->config = $config;
58
            $this->config['tmp_folder'] = __DIR__ . '/assets';
59
            $this->config['tmp_file_mask'] = 'tmp%2$s/%1$s.csv';
60
            $this->config['tmp_table_mask'] = 'tmp_%1$s_%2$s';
61
            $this->config['local_infile'] = true;
62
            $this->resource = new DBALMysqlResource($this->config);
63
            $ref1 = new \ReflectionProperty(get_class($this->resource->getConnection()), '_conn');
64
            $ref1->setAccessible(true);
65
            $this->pdo = $ref1->getValue($this->resource->getConnection());
66
        } else {
67
            throw new \Exception("Can't find config file.");
68
        }
69
70
        parent::setUp();
71
72
        // assert that 2 pdo's are same
73
        $pdo1 = $this->getConnection()->getConnection();
74
        $pdo2 = $ref1->getValue($this->resource->getConnection());
75
76
        $this->assertSame($pdo1, $pdo2);
77
    }
78
79
    protected function tearDown()
80
    {
81
        parent::tearDown();
82
        $this->resource->close();
83
    }
84
85
    /**
86
     * Set Up Schema
87
     */
88
    public static function setUpBeforeClass()
89
    {
90
        require_once __DIR__ . '/bootstrap.php';
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    protected function getConnection()
97
    {
98
        if (isset($this->pdo)) {
99
            return $this->createDefaultDBConnection($this->pdo);
100
        }
101
        throw new \Exception("Can't find pdo in config.");
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    protected function getTearDownOperation()
108
    {
109
        if ($this->config['db_debug']) {
110
            return \PHPUnit_Extensions_Database_Operation_Factory::NONE();
111
        }
112
        return \PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE();
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    protected function getDataSet()
119
    {
120
        return $this->createXMLDataSet(__DIR__ . '/assets/initialStructure.xml');
121
    }
122
123
    /**
124
     * @return LanguageAdapter
125
     */
126
    public function getLanguageAdapter()
127
    {
128
        $language = new ExpressionLanguage();
129
        $language->registerProvider(new HelperExpressionsProvider());
130
        return new LanguageAdapter($language);
131
    }
132
133
    /**
134
     * @return Unit
135
     * @throws \Doctrine\DBAL\DBALException
136
     */
137
    public function prepareCustomerImportUnit()
138
    {
139
        $customerUnit = new Unit('customers');
140
        $customerUnit->setTable('customers');
141
        $hashMap = new ArrayHashmap('email-id');
142
        $hashMap->load($this->resource->getConnection()
143
            ->executeQuery("SELECT email,id FROM customers")
144
            ->fetchAll(\PDO::FETCH_KEY_PAIR));
145
        $customerUnit->addHashmap($hashMap);
146
        $contribution1 = <<<CONTRIBUTION
147
map.offsetSet(
148
    'customer_id',
149
    (isset(hashmaps['email-id'][trim(map.email)]) ?
150
        hashmaps['email-id'][trim(map.email)] :
151
        map.frozenIncr('new_customer_id', 3))
152
)
153
CONTRIBUTION;
154
        $customerUnit->addContribution($contribution1);
155
        $contribution2 = <<<CONTRIBUTION
156
map.offsetSet(
157
    'complexName',
158
    explode(' ', map.name)
159
)
160
CONTRIBUTION;
161
        $customerUnit->addContribution($contribution2);
162
        $contribution3 = <<<CONTRIBUTION
163
map.offsetSet(
164
    'firstname',
165
    (count(map.complexName) >= 2 && isset(map.complexName[0]) ? map.complexName[0] : map.name)
166
)
167
CONTRIBUTION;
168
        $customerUnit->addContribution($contribution3);
169
        $contribution4 = <<<CONTRIBUTION
170
map.offsetSet(
171
    'lastname',
172
    (count(map.complexName) >= 2 && isset(map.complexName[1]) ? map.complexName[1] : '')
173
)
174
CONTRIBUTION;
175
        $customerUnit->addContribution($contribution4);
176
        $customerUnit->setMapping([
177
            'id' => 'map.customer_id',
178
            'firstname' => 'map.firstname',
179
            'lastname' => 'map.lastname',
180
            'age' => 'map.age',
181
            'email' => 'trim(map.email)',
182
        ]);
183
        $customerUnit->setIsEntityCondition("trim(map.email) != trim(oldmap.email)");
184
        return $customerUnit;
185
    }
186
187
    /**
188
     * @return Unit
189
     */
190
    public function prepareAddressImportUnit()
191
    {
192
        $addressUnit = new Unit("addresses");
193
        $addressUnit->setTable('addresses');
194
        $addressUnit->setMapping([
195
            'id' => 'map.incr("address_id", 4)',
196
            'street' => 'map.street',
197
            'city' => 'map.city',
198
            'parent_id' => 'map.customer_id',
199
        ]);
200
        return $addressUnit;
201
    }
202
203
    /**
204
     * @test
205
     * @throws \Doctrine\DBAL\DBALException
206
     */
207
    public function testSimpleImport()
208
    {
209
        // SET THESE TO TRUE TO DEBUG
210
        $this->config['db_debug'] = false;
211
        $this->config['file_debug'] = false;
212
        //=====================================================================
213
        $customerUnit = $this->prepareCustomerImportUnit();
214
        $addressUnit = $this->prepareAddressImportUnit();
215
        $addressUnit->setParent($customerUnit);
216
        //=====================================================================
217
        $bag = new SimpleBag();
218
        // order matters ;)
219
        $bag->add($customerUnit);
220
        $bag->add($addressUnit);
221
        //=====================================================================
222
        $input = new Csv(__DIR__ . '/assets/customers_1.csv', 'r', new Duplicates(
223
            $bag,
224
            new ArrayMap(),
225
            $this->getLanguageAdapter())
226
        );
227
        $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(),
228
            $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
229
        $load = new Load($bag, $this->config, $this->resource);
230
        $move = new Move($bag, $this->config, $this->resource);
231
        //=====================================================================
232
        $result = new Result();
233
        $workflow = new QueueWorkflow($this->config, $result);
234
        $workflow->add($createTmpFiles);
235
        $workflow->add($load);
236
        $workflow->add($move);
237
        $workflow->execute();
238
        //=====================================================================
239
        // time to assert things
240
241
        // assert schema
242
        $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterSimpleImportStructure.xml');
243
        $actual = $this->getConnection()->createDataSet(['customers', 'addresses']);
244
        $this->assertDataSetsEqual($expected, $actual);
245
    }
246
247
    /**
248
     * @test
249
     * @throws \Doctrine\DBAL\DBALException
250
     */
251
    public function testSimpleImport2Nulls()
252
    {
253
        // SET THESE TO TRUE TO DEBUG
254
        $this->config['db_debug'] = false;
255
        $this->config['file_debug'] = false;
256
        //=====================================================================
257
        $customerUnit = $this->prepareCustomerImportUnit();
258
        $addressUnit = $this->prepareAddressImportUnit();
259
        $addressUnit->setParent($customerUnit);
260
        //=====================================================================
261
        $bag = new SimpleBag();
262
        // order matters ;)
263
        $bag->add($customerUnit);
264
        $bag->add($addressUnit);
265
        //=====================================================================
266
        $input = new Csv(__DIR__ . '/assets/customers_2_nulls.csv', 'r', new Nulls(
267
            $bag,
268
            new ArrayMap(),
269
            $this->getLanguageAdapter())
270
        );
271
        $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(),
272
            $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
273
        $load = new Load($bag, $this->config, $this->resource);
274
        $move = new Move($bag, $this->config, $this->resource);
275
        //=====================================================================
276
        $result = new Result();
277
        $workflow = new QueueWorkflow($this->config, $result);
278
        $workflow->add($createTmpFiles);
279
        $workflow->add($load);
280
        $workflow->add($move);
281
        $workflow->execute();
282
        //=====================================================================
283
        // time to assert things
284
285
        // assert schema
286
        $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterSimpleImportStructure.xml');
287
        $actual = $this->getConnection()->createDataSet(['customers', 'addresses']);
288
        $this->assertDataSetsEqual($expected, $actual);
289
    }
290
291
    /**
292
     * @test
293
     */
294
    public function testImportWithExisting()
295
    {
296
        // SET THESE TO TRUE TO DEBUG
297
        $this->config['db_debug'] = false;
298
        $this->config['file_debug'] = false;
299
        //=====================================================================
300
        $customerUnit = $this->prepareCustomerImportUnit();
301
        $addressUnit = $this->prepareAddressImportUnit();
302
        $addressUnit->setParent($customerUnit);
303
        //=====================================================================
304
        // order matters ;)
305
        $bag = new SimpleBag();
306
        $bag->add($customerUnit);
307
        $bag->add($addressUnit);
308
        //=====================================================================
309
        $input = new Csv(__DIR__ . '/assets/customers_2.csv', 'r', new Duplicates(
310
            $bag,
311
            new ArrayMap(),
312
            $this->getLanguageAdapter())
313
        );
314
        $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(),
315
            $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
316
        $load = new Load($bag, $this->config, $this->resource);
317
        $move = new Move($bag, $this->config, $this->resource);
318
        //=====================================================================
319
        $result = new Result();
320
        $workflow = new QueueWorkflow($this->config, $result);
321
        $workflow->add($createTmpFiles);
322
        $workflow->add($load);
323
        $workflow->add($move);
324
        $workflow->execute();
325
        //=====================================================================
326
        // time to assert things
327
328
        // assert schema
329
        $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterImportWithExistingStructure.xml');
330
        $actual = $this->getConnection()->createDataSet(['customers', 'addresses']);
331
        $this->assertDataSetsEqual($expected, $actual);
332
    }
333
334
    /**
335
     * @test
336
     */
337
    public function testImportDeleteAddresses()
338
    {
339
        // SET THESE TO TRUE TO DEBUG
340
        $this->config['db_debug'] = false;
341
        $this->config['file_debug'] = false;
342
        //=====================================================================
343
        $customerUnit = $this->prepareCustomerImportUnit();
344
        $addressUnit = $this->prepareAddressImportUnit();
345
        $addressUnit->setParent($customerUnit);
346
        //=====================================================================
347
        // order matters ;)
348
        $bag = new SimpleBag();
349
        $bag->add($customerUnit);
350
        $bag->add($addressUnit);
351
        //=====================================================================
352
        $input = new Csv(__DIR__ . '/assets/customers_2.csv', 'r', new Duplicates(
353
            $bag,
354
            new ArrayMap(),
355
            $this->getLanguageAdapter())
356
        );
357
        $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(),
358
            $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
359
        $load = new Load($bag, $this->config, $this->resource);
360
        $move = new Move($bag, $this->config, $this->resource);
361
        //=====================================================================
362
        $deleteAddressUnit = new Unit('deleteAddress');
363
        $deleteAddressUnit->setTable('addresses');
364
        $deleteAddressUnit->addWriteCondition("isset(map.address_id)");
365
        $contribution = <<<CONTRIBUTION
366
map.offsetSet(
367
    'address_id',
368
    (isset(hashmaps['email-address'][trim(map.email)]) ?
369
        hashmaps['email-address'][trim(map.email)] :
370
        null)
371
)
372
CONTRIBUTION;
373
374
        $deleteAddressUnit->addContribution($contribution);
375
        $deleteAddressUnit->setMapping(['id' => 'explode(",", map.address_id)']);
376
377
        $hashMap = new ArrayHashmap('email-address');
378
        $sql = <<<MYSQL
379
SELECT c.email,GROUP_CONCAT(a.id) FROM customers c
380
LEFT JOIN addresses a ON a.parent_id = c.id
381
GROUP BY c.email
382
MYSQL;
383
384
        $hashMap->load($this->resource->getConnection()
385
            ->executeQuery($sql)
386
            ->fetchAll(\PDO::FETCH_KEY_PAIR));
387
        $deleteAddressUnit->addHashmap($hashMap);
388
        $deleteAddressUnit->setPk('id');
389
390
        $deleteBag = new SimpleBag();
391
        $deleteBag->add($deleteAddressUnit);
392
393
        $delCreateTmpFiles = new CreateTmpFiles($deleteBag, $this->config, $this->getLanguageAdapter(),
394
            $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
395
        $delLoad = new Load($deleteBag, $this->config, $this->resource);
396
        $delete = new Delete($deleteBag, $this->config, $this->resource);
397
        //=====================================================================
398
        $result = new Result();
399
        $workflow = new QueueWorkflow($this->config, $result);
400
        $workflow->add($createTmpFiles);
401
        $workflow->add($load);
402
        $workflow->add($delCreateTmpFiles);
403
        $workflow->add($delLoad);
404
        $workflow->add($delete);
405
        $workflow->add($move);
406
        try {
407
            $this->resource->startTransaction();
408
            $workflow->execute();
409
            $this->resource->commit();
410
        } catch (\Exception $e) {
411
            $this->resource->rollback();
412
            throw $e;
413
        }
414
        //=====================================================================
415
        // time to assert things
416
417
        // assert schema
418
        $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterImportDeleteAddressStructure.xml');
419
        $actual = $this->getConnection()->createDataSet(['customers', 'addresses']);
420
        $this->assertDataSetsEqual($expected, $actual);
421
    }
422
423
    /**
424
     * @test
425
     * @throws \Doctrine\DBAL\DBALException
426
     * @throws \Exception
427
     */
428
    public function testImportGenerate()
429
    {
430
        // SET THESE TO TRUE TO DEBUG
431
        $this->config['db_debug'] = false;
432
        $this->config['file_debug'] = false;
433
        //=====================================================================
434
        $bag = new SimpleBag();
435
        $cu = $this->getGenerateCustomerUnit();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $cu. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
436
        $au = $this->getGenerateAddressUnit();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $au. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
437
        $au->setParent($cu);
438
        $bag->add($cu);
439
        $bag->add($au);
440
441
        $generator = new Generator();
442
        $generator->addProvider(new Base($generator));
443
        $generator->addProvider(new Lorem($generator));
444
        $generator->addProvider(new Person($generator));
445
        $generator->addProvider(new Address($generator));
446
        $generator->addProvider(new Internet($generator));
447
448
        // truncate all info beforehand to not run into issue with duplicate email
449
        $this->resource->getConnection()->executeUpdate("DELETE FROM customers");
450
451
        $generate = new Generate($bag, $this->config, $this->getLanguageAdapter(),
452
            $generator, 100, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
453
        $load = new Load($bag, $this->config, $this->resource);
454
        $move = new Move($bag, $this->config, $this->resource);
455
456
        $result = new Result();
457
        $workflow = new QueueWorkflow($this->config, $result);
458
        $workflow->add($generate);
459
        $workflow->add($load);
460
        $workflow->add($move);
461
        try {
462
            $this->resource->startTransaction();
463
            $workflow->execute();
464
            $this->resource->commit();
465
        } catch (\Exception $e) {
466
            $this->resource->rollback();
467
            throw $e;
468
        }
469
470
        $this->assertTableRowCount('customers', 100);
471
    }
472
473
    /**
474
     * @return Unit
475
     */
476
    protected function getGenerateCustomerUnit()
477
    {
478
        $customerUnit = new Unit('customers');
479
        $customerUnit->setGeneratorMapping([
480
            'id' => 'map.frozenIncr("customer_id", resource.getLastIncrement("customers"))',
481
            'firstname' => 'generator.firstName',
482
            'lastname' => 'generator.lastName',
483
            'age' => 'generator.numberBetween(10, 60)',
484
            'email' => 'generator.unique().email',
485
        ]);
486
        $customerUnit->setMapping([
487
            'id' => "",
488
            'firstname' => "",
489
            'lastname' => "",
490
            'age' => "",
491
            'email' => "",
492
        ]);
493
        $customerUnit->setTable("customers");
494
        return $customerUnit;
495
    }
496
497
    protected function getGenerateAddressUnit()
498
    {
499
        $addressUnit = new Unit('addresses');
500
        $seed = new \SplFixedArray(2);
501
        $seed[0] = 4;
502
        $seed[1] = 1;
503
        $addressUnit->setGenerationSeed($seed);
504
        $addressUnit->setGeneratorMapping([
505
            'id' => 'map.incr("address_id", resource.getLastIncrement("addresses"))',
506
            'parent_id' => 'map.customer_id',
507
            'street' => 'generator.streetAddress',
508
            'city' => 'generator.city',
509
        ]);
510
        $addressUnit->setMapping([
511
            'id' => '',
512
            'parent_id' => '',
513
            'street' => '',
514
            'city' => '',
515
        ]);
516
        $addressUnit->setTable('addresses');
517
        return $addressUnit;
518
    }
519
520
    /**
521
     * @test
522
     */
523
    public function testGenerateExport()
524
    {
525
        // SET THESE TO TRUE TO DEBUG
526
        $this->config['db_debug'] = false;
527
        $this->config['file_debug'] = false;
528
        //=====================================================================
529
        $cUnit = $this->getGenerateCustomerUnit();
530
        $cUnit->setReversedConnection([
531
            'customer_id' => 'id',
532
        ]);
533
        $cUnit->setReversedMapping([
534
            'email' => 'map.email',
535
            'name' => 'map.firstname ~ " " ~ map.lastname',
536
            'age' => 'map.age',
537
        ]);
538
        $aUnit = $this->getGenerateAddressUnit();
539
        $aUnit->setReversedConnection([
540
            'customer_id' => 'parent_id',
541
        ]);
542
        $aUnit->setReversedMapping([
543
            'street' => 'map.street',
544
            'city' => 'map.city',
545
        ]);
546
        $aUnit->setParent($cUnit);
547
548
        $bag = new SimpleBag();
549
        $bag->add($cUnit);
550
        $bag->add($aUnit);
551
552
        $generator = new Generator();
553
        $generator->addProvider(new Base($generator));
554
        $generator->addProvider(new Lorem($generator));
555
        $generator->addProvider(new Person($generator));
556
        $generator->addProvider(new Address($generator));
557
        $generator->addProvider(new Internet($generator));
558
559
        // truncate all info beforehand to not run into issue with duplicate email
560
        $this->resource->getConnection()->executeUpdate("DELETE FROM customers");
561
562
        $fname = __DIR__ . '/assets/results/customers_generated.csv';
563
        $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter()));
564
565
        $generate = new Generate($bag, $this->config, $this->getLanguageAdapter(),
566
            $generator, 100, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
567
        $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap());
568
569
        $result = new Result();
570
        $workflow = new QueueWorkflow($this->config, $result);
571
        $workflow->add($generate);
572
        $workflow->add($assemble);
573
574
        $workflow->execute();
575
        //=====================================================================
576
        // assert that customers are in the file
577
578
        $this->assertFileExists($fname);
579
        $this->assertGreaterThan(100, $this->getNumberOfLines($fname));
580
    }
581
582
    /**
583
     * @test
584
     */
585
    public function testGenerateExport2Branches()
586
    {
587
        // SET THESE TO TRUE TO DEBUG
588
        $this->config['db_debug'] = false;
589
        $this->config['file_debug'] = false;
590
        //=====================================================================
591
        $cUnit = $this->getGenerateCustomerUnit();
592
        $cUnit->setReversedConnection([
593
            'customer_id' => 'id',
594
        ]);
595
        $cUnit->setReversedMapping([
596
            'email' => 'map.email',
597
            'age' => 'map.age',
598
        ]);
599
        $cdUnit = new Unit('customer_data');
600
        $seed = new \SplFixedArray(2);
601
        $seed[0] = 1;
602
        $seed[1] = 1;
603
        $cdUnit->setGenerationSeed($seed);
604
        $cdUnit->setGeneratorMapping([
605
            'id' => 'map.incr("gen_id", 1)',
606
            'parent_id' => 'map.customer_id',
607
            'firstname' => 'generator.firstName',
608
            'lastname' => 'generator.lastName',
609
        ]);
610
        $cdUnit->setMapping([
611
            'id' => '',
612
            'parent_id' => '',
613
            'firstname' => '',
614
            'lastname' => '',
615
        ]);
616
        $cdUnit->setTable('customers');
617
        $cdUnit->setReversedConnection([
618
            'customer_id' => 'parent_id',
619
        ]);
620
        $cdUnit->setReversedMapping([
621
            'name' => 'map.firstname ~ " " ~ map.lastname',
622
        ]);
623
        $cdUnit->addSibling($cUnit);
624
625
        $bag = new SimpleBag();
626
        $bag->add($cUnit);
627
        $bag->add($cdUnit);
628
629
        $generator = new Generator();
630
        $generator->addProvider(new Base($generator));
631
        $generator->addProvider(new Lorem($generator));
632
        $generator->addProvider(new Person($generator));
633
        $generator->addProvider(new Address($generator));
634
        $generator->addProvider(new Internet($generator));
635
636
        // truncate all info beforehand to not run into issue with duplicate email
637
        $this->resource->getConnection()->executeUpdate("DELETE FROM customers");
638
639
        $fname = __DIR__ . '/assets/results/customers_data_generated.csv';
640
        $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter()));
641
642
        $generate = new Generate($bag, $this->config, $this->getLanguageAdapter(),
643
            $generator, 100, new ArrayMap(), new DBALMysqlResourceHelper($this->resource));
644
        $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap());
645
646
        $result = new Result();
647
        $workflow = new QueueWorkflow($this->config, $result);
648
        $workflow->add($generate);
649
        $workflow->add($assemble);
650
651
        $workflow->execute();
652
        //=====================================================================
653
        // assert that customers are in the file
654
655
        $this->assertFileExists($fname);
656
        $this->assertEquals(101, $this->getNumberOfLines($fname));
657
    }
658
659
    /**
660
     * @test
661
     */
662
    public function testSimpleExport()
663
    {
664
        // SET THESE TO TRUE TO DEBUG
665
        $this->config['db_debug'] = false;
666
        $this->config['file_debug'] = false;
667
        //=====================================================================
668
        $this->config['dump_limit'] = 100;
669
670
        $cUnit = new Unit('customers');
671
        $aUnit = new Unit('addresses');
672
        //=====================================================================
673
        $cUnit->setTable('customers');
674
        $aUnit->setTable('addresses');
675
        $cUnit->setReverseMoveOrder(['id']);
676
        $cUnit->setReverseMoveDirection('asc');
677
        $aUnit->setReverseMoveOrder(['parent_id']);
678
        $aUnit->setReverseMoveDirection('asc');
679
        //=====================================================================
680
        $cUnit->setMapping([
681
            'id' => "",
682
            'firstname' => "",
683
            'lastname' => "",
684
            'age' => "",
685
            'email' => "",
686
        ]);
687
        $aUnit->setMapping([
688
            'id' => '',
689
            'parent_id' => '',
690
            'street' => '',
691
            'city' => '',
692
        ]);
693
        $cUnit->setReversedConnection([
694
            'customer_id' => 'id',
695
        ]);
696
        $cUnit->setReversedMapping([
697
            'email' => 'map.email',
698
            'name' => 'map.firstname ~ " " ~ map.lastname',
699
            'age' => 'map.age',
700
        ]);
701
        $aUnit->setReversedConnection([
702
            'customer_id' => 'parent_id',
703
        ]);
704
        $aUnit->setReversedMapping([
705
            'street' => 'map.street',
706
            'city' => 'map.city',
707
        ]);
708
        $aUnit->setParent($cUnit);
709
        //=====================================================================
710
        $bag = new SimpleBag();
711
        $bag->addSet([$cUnit, $aUnit]);
712
713
        $fname = __DIR__ . '/assets/results/customers_data_exported.csv';
714
        $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter()));
715
716
        $reverseMove = new ReverseMove($bag, $this->config, $this->resource);
717
        $dump = new Dump($bag, $this->config, $this->resource);
718
        $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap());
719
720
        $result = new Result();
721
        $workflow = new QueueWorkflow($this->config, $result);
722
        $workflow->add($reverseMove);
723
        $workflow->add($dump);
724
        $workflow->add($assemble);
725
726
        $workflow->execute();
727
        //=====================================================================
728
        // assert that customers are in the file
729
730
        $this->assertFileExists($fname);
731
        $this->assertEquals(4, $this->getNumberOfLines($fname));
732
    }
733
734
    public function testExportNull()
735
    {
736
        // SET THESE TO TRUE TO DEBUG
737
        $this->config['db_debug'] = false;
738
        $this->config['file_debug'] = false;
739
        //=====================================================================
740
        $this->config['dump_limit'] = 100;
741
742
        $cUnit = new Unit('customers');
743
        //=====================================================================
744
        $cUnit->setTable('customers');
745
        $cUnit->setReverseMoveOrder(['id']);
746
        $cUnit->setReverseMoveDirection('asc');
747
        //=====================================================================
748
        $cUnit->setMapping([
749
            'id' => "",
750
            'firstname' => "",
751
            'lastname' => "",
752
            'age' => "",
753
            'email' => "",
754
        ]);
755
        $cUnit->setReversedConnection([
756
            'customer_id' => 'id',
757
        ]);
758
        $cUnit->setReversedMapping([
759
            'email' => 'map.email',
760
            'name' => 'map.firstname ~ " " ~ map.lastname',
761
            'age' => 'map.age',
762
        ]);
763
        //=====================================================================
764
        $bag = new SimpleBag();
765
        $bag->add($cUnit);
766
767
        // truncate all info beforehand to not run into issue with duplicate email
768
        $this->resource->getConnection()->executeUpdate("DELETE FROM customers");
769
        $this->resource->getConnection()->insert('customers', [
770
            'id' => 1,
771
            'firstname' => 'test1',
772
            'lastname' => 'test1',
773
            'age' => null,
774
            'email' => '[email protected]',
775
        ]);
776
777
        $fname = __DIR__ . '/assets/results/customers_data_exported_with_nulls.csv';
778
        $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter()));
779
780
        $reverseMove = new ReverseMove($bag, $this->config, $this->resource);
781
        $dump = new Dump($bag, $this->config, $this->resource);
782
        $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap());
783
784
        $result = new Result();
785
        $workflow = new QueueWorkflow($this->config, $result);
786
        $workflow->add($reverseMove);
787
        $workflow->add($dump);
788
        $workflow->add($assemble);
789
790
        $workflow->execute();
791
        //=====================================================================
792
        // assert that customers are in the file
793
794
        $this->assertFileExists($fname);
795
        $this->assertEquals(2, $this->getNumberOfLines($fname));
796
        $csvObject = new \SplFileObject($fname, 'r');
797
        $csvObject->fgetcsv();
798
        $actual = $csvObject->fgetcsv();
799
        $this->assertEquals([
800
            '[email protected]',
801
            'test1 test1',
802
            '\N',
803
        ], $actual);
804
    }
805
806
    /**
807
     * @param string $fname
808
     * @return int
809
     */
810
    public function getNumberOfLines($fname)
811
    {
812
        $fileObject = new \SplFileObject($fname, 'r');
813
        $i = 0;
814
        while (!$fileObject->eof()) {
815
            $fileObject->next();
816
            $current = $fileObject->current();
817
            if (!empty($current)) {
818
                $i++;
819
            }
820
        }
821
        return $i;
822
    }
823
}
824