TableContext::findTables()   B
last analyzed

Complexity

Conditions 5
Paths 3

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 16
nc 3
nop 0
1
<?php
2
3
namespace Knp\FriendlyContexts\Context;
4
5
use Behat\Gherkin\Node\TableNode;
6
use Knp\FriendlyContexts\Utils\Asserter;
7
use Knp\FriendlyContexts\Utils\TextFormater;
8
9
class TableContext extends RawMinkContext
10
{
11
    /**
12
     * @Then /^I should see a table with "([^"]*)" in the "([^"]*)" column$/
13
     */
14
    public function iShouldSeeATableWithInTheNamedColumn($list, $column)
15
    {
16
        $cells = array_merge(array($column), $this->getFormater()->listToArray($list));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
17
        $expected = new TableNode(array_map(function($cell) { return [$cell]; }, $cells));
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
18
19
        $this->iShouldSeeTheFollowingTable($expected);
20
    }
21
22
    /**
23
     * @Given /^I should see the following table:?$/
24
     */
25
    public function iShouldSeeTheFollowingTable($expected)
26
    {
27
        if ($expected instanceof TableNode) {
28
            $expected = $expected->getTable();
29
        }
30
31
        $this->iShouldSeeATable();
32
33
        $tables = $this->findTables();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
34
        $exceptions = array();
35
36 View Code Duplication
        foreach ($tables as $table) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
37
            try {
38
                if (false === $extraction = $this->extractColumns(current($expected), $table)) {
39
                    $this->getAsserter()->assertArrayEquals($expected, $table, true);
40
41
                    return;
42
                }
43
                $this->getAsserter()->assertArrayEquals($expected, $extraction, true);
44
45
                return;
46
            } catch (\Exception $e) {
47
                $exceptions[] = $e;
48
            }
49
        }
50
51
        $message = implode("\n", array_map(function ($e) { return $e->getMessage(); }, $exceptions));
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
52
53
        throw new \Exception($message);
54
    }
55
56
    /**
57
     * @Then /^I should see the following table portion:?$/
58
     */
59
    public function iShouldSeeTheFollowingTablePortion($expected)
60
    {
61
        if ($expected instanceof TableNode) {
62
            $expected = $this->reorderArrayKeys($expected->getTable());
63
        }
64
65
        $this->iShouldSeeATable();
66
67
        $tables = $this->findTables();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
68
        $exceptions = array();
69
70 View Code Duplication
        foreach ($tables as $table) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
            try {
72
                if (false === $extraction = $this->extractColumns(current($expected), $table)) {
73
                    $this->getAsserter()->assertArrayContains($expected, $table);
74
75
                    return;
76
                }
77
                $this->getAsserter()->assertArrayContains($expected, $extraction);
78
79
                return;
80
            } catch (\Exception $e) {
81
                $exceptions[] = $e;
82
            }
83
        }
84
85
        $message = implode("\n", array_map(function ($e) { return $e->getMessage(); }, $exceptions));
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
86
87
        throw new \Exception($message);
88
    }
89
90
    /**
91
     * @Then /^I should see a table with ([^"]*) rows$/
92
     * @Then /^I should see a table with ([^"]*) row$/
93
     */
94
    public function iShouldSeeATableWithRows($nbr)
95
    {
96
        $nbr = (int) $nbr;
97
98
        $this->iShouldSeeATable();
99
        $exceptions = array();
100
        $tables = $this->getSession()->getPage()->findAll('css', 'table');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
101
102
        foreach ($tables as $table) {
103
            try {
104
                if (null !== $body = $table->find('css', 'tbody')) {
105
                    $table = $body;
106
                }
107
                $rows = $table->findAll('css', 'tr');
108
                $this->getAsserter()->assertEquals($nbr, count($rows), sprintf('Table with %s rows expected, table with %s rows found.', $nbr, count($rows)));
109
                return;
110
            } catch (\Exception $e) {
111
                $exceptions[] = $e;
112
            }
113
        }
114
115
        $message = implode("\n", array_map(function ($e) { return $e->getMessage(); }, $exceptions));
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
116
117
        throw new \Exception($message);
118
    }
119
120
    /**
121
     * @Then /^I should see a table$/
122
     */
123
    public function iShouldSeeATable()
124
    {
125
        try {
126
            $this->getSession()->wait(2000, '0 < document.getElementsByTagName("TABLE").length');
127
        } catch (\Exception $ex) {
128
            unset($ex);
129
        }
130
        $tables = $this->getSession()->getPage()->findAll('css', 'table');
131
        $this->getAsserter()->assert(0 < count($tables), 'No table found');
132
    }
133
134
    protected function extractColumns(array $headers, array $table)
135
    {
136
        if (0 == count($table) || 0 == count($headers)) {
137
            return false;
138
        }
139
140
        $columns = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
141
        $tableHeaders = current($table);
142
        foreach ($headers as $header) {
143
            $inArray = false;
144
            foreach ($tableHeaders as $index => $thead) {
145
                if ($thead === $header) {
146
                    $columns[] = $index;
147
                    $inArray = true;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
148
                }
149
            }
150
            if (false === $inArray) {
151
                return false;
152
            }
153
        }
154
155
        $result = array();
156
        foreach ($table as $row) {
157
            $node = array();
158
            foreach ($row as $index => $value) {
159
                if (in_array($index, $columns)) {
160
                    $node[] = $value;
161
                }
162
            }
163
            $result[] = $node;
164
        }
165
166
        return $result;
167
    }
168
169
    protected function findTables()
170
    {
171
        $tables = $this->getSession()->getPage()->findAll('css', 'table');
172
        $result = array();
173
174
        foreach ($tables as $table) {
175
            $node = array();
176
            $head = $table->find('css', 'thead');
177
            $body = $table->find('css', 'tbody');
178
            $foot = $table->find('css', 'tfoot');
179
            if (null !== $head || null !== $body || null !== $foot) {
180
                $this->extractDataFromPart($head, $node);
181
                $this->extractDataFromPart($body, $node);
182
                $this->extractDataFromPart($foot, $node);
183
            } else {
184
                $this->extractDataFromPart($table, $node);
185
            }
186
            $result[] = $node;
187
        }
188
189
        return $result;
190
    }
191
192
    protected function extractDataFromPart($part, &$array)
193
    {
194
        if (null === $part) {
195
196
            return;
197
        }
198
199
        foreach ($part->findAll('css', 'tr') as $row) {
200
            $array[] = $this->extractDataFromRow($row);
201
        }
202
    }
203
204
    protected function extractDataFromRow($row)
205
    {
206
        $result = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
207
        $elements = array_merge($row->findAll('css', 'th'), $row->findAll('css', 'td'));
208
209
        foreach ($elements as $element) {
210
            $result[] = preg_replace('!\s+!', ' ', $element->getText());
211
        }
212
213
        return $result;
214
    }
215
216
    protected function reorderArrayKeys(array $subject)
217
    {
218
        $orderedArray = array();
219
220
        foreach ($subject as $key => $value) {
221
            if (is_int($key)) {
222
                $orderedArray[] = $value;
223
            } else {
224
                $orderedArray[$key] = $value;
225
            }
226
        }
227
228
        return $orderedArray;
229
    }
230
231
    protected function getAsserter()
232
    {
233
        return new Asserter($this->getFormater());
234
    }
235
236
    protected function getFormater()
237
    {
238
        return new TextFormater;
239
    }
240
}
241