Completed
Pull Request — master (#8)
by Саша
21:35
created

DefaultPipelineContext   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14
Metric Value
wmc 13
lcom 1
cbo 14
dl 0
loc 128
rs 10
1
<?php
2
3
use Behat\Gherkin\Node\TableNode;
4
use Behat\Behat\Context\Context;
5
use Behat\Behat\Context\SnippetAcceptingContext;
6
use Behat\Behat\Tester\Exception\PendingException;
7
use Doctrine\DBAL\DriverManager;
8
use Behat\Gherkin\Node\PyStringNode;
9
use Symfony\Component\Console\Helper\Table;
10
use Symfony\Component\Console\Output\BufferedOutput;
11
use Extraload\Pipeline\DefaultPipeline;
12
use Extraload\Extractor\CsvExtractor;
13
use Extraload\Transformer\CallbackTransformer;
14
use Extraload\Transformer\TransformerChain;
15
use Extraload\Loader\ConsoleLoader;
16
use Extraload\Loader\Doctrine\DbalLoader;
17
18
class DefaultPipelineContext extends BaseContext implements Context, SnippetAcceptingContext
19
{
20
    private $workingTable = 'book';
21
    private $workingFile;
22
    private $pipeline;
23
    private $output;
24
    private $connection;
25
26
    /**
27
     * @Given a file named :name with:
28
     */
29
    public function aFileNamedWith($name, PyStringNode $content)
30
    {
31
        $this->workingFile = $this->createFileFromStringNode($name, $content);
32
    }
33
34
    /**
35
     * @Given I create csv to console pipeline using :transformer transformer
36
     */
37
    public function iCreateCsvToConsolePipelineUsingTransformer($transformer)
38
    {
39
        return $this->pipeline = new DefaultPipeline(
40
            $this->createCsvExtractor(),
41
            $this->createTransformer($transformer),
42
            new ConsoleLoader(
43
                new Table($this->output = new BufferedOutput())
44
            )
45
        );
46
    }
47
48
    /**
49
     * @Given I create csv to database pipeline
50
     */
51
    public function iCreateCsvToDatabasePipeline()
52
    {
53
        return $this->pipeline = new DefaultPipeline(
54
            $this->createCsvExtractor(),
55
            $this->createTransformer('callable'),
56
            new DbalLoader(
57
                $this->getConnection(),
58
                $this->workingTable
59
            )
60
        );
61
    }
62
63
    /**
64
     * @Given I process it
65
     */
66
    public function iProcessIt()
67
    {
68
        $this->pipeline->process();
69
    }
70
71
    /**
72
     * @Then I should see in console:
73
     */
74
    public function iShouldSeeInConsole(PyStringNode $expected)
75
    {
76
        $expected = $this->stringNodeToString($expected);
77
        $actual = trim($this->output->fetch());
78
79
        PHPUnit_Framework_Assert::assertEquals($expected, $actual);
80
    }
81
82
    /**
83
     * @Then I should see in database:
84
     */
85
    public function iShouldSeeInDatabase(TableNode $table)
86
    {
87
        $actual = $this->getConnection()
88
            ->createQueryBuilder()
89
            ->select('*')
90
            ->from($this->workingTable)
91
            ->execute()
92
            ->fetchAll()
93
        ;
94
95
        foreach ($table->getHash() as $key => $expected) {
96
            PHPUnit_Framework_Assert::assertEquals($expected, $actual[$key]);
97
        }
98
    }
99
100
    private function createCsvExtractor()
101
    {
102
        return new CsvExtractor(new \SplFileObject($this->workingFile));
103
    }
104
105
    private function createTransformer($type)
106
    {
107
        switch ($type) {
108
            case 'callable':
109
                return new CallbackTransformer(function ($data) {
110
                    return [
111
                        'isbn' => $data[0],
112
                        'title' => $data[1],
113
                        'author' => $data[2],
114
                    ];
115
                });
116
117
            case 'chain':
118
                return new TransformerChain([
119
                    new CallbackTransformer(function ($data) {
120
                        unset($data[0]);
121
122
                        return $data;
123
                    }),
124
                    new CallbackTransformer(function ($data) {
125
                        return [
126
                            'title' => $data[1],
127
                            'author' => $data[2],
128
                        ];
129
                    }),
130
                ]);
131
        }
132
133
        throw new PendingException(sprintf('Implement %s transformer creator.', $type));
134
    }
135
136
    private function getConnection()
137
    {
138
        if (null === $this->connection) {
139
            $this->connection = DriverManager::getConnection(['url' => 'sqlite:///:memory:']);
140
            $this->connection->exec(sprintf('CREATE TABLE %s(isbn, title, author)', $this->workingTable));
141
        }
142
143
        return $this->connection;
144
    }
145
}
146