Completed
Pull Request — master (#298)
by
unknown
03:49
created

CsvReaderTest::testMaximumNesting()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 30
rs 8.439
cc 5
eloc 18
nc 16
nop 0
1
<?php
2
3
namespace Ddeboer\DataImport\Tests\Reader;
4
5
use Ddeboer\DataImport\Reader\CsvReader;
6
7
class CsvReaderTest extends \PHPUnit_Framework_TestCase
8
{
9
    public function testReadCsvFileWithColumnHeaders()
10
    {
11
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_column_headers.csv');
12
        $csvReader = new CsvReader($file);
13
        $csvReader->setHeaderRowNumber(0);
14
15
        $this->assertEquals(
16
            array(
17
                'id', 'number', 'description'
18
            ),
19
            $csvReader->getFields()
20
        );
21
22
        foreach ($csvReader as $row) {
23
            $this->assertNotNull($row['id']);
24
            $this->assertNotNull($row['number']);
25
            $this->assertNotNull($row['description']);
26
        }
27
28
        $this->assertEquals(
29
            array(
30
                'id'        => 6,
31
                'number'    => '456',
32
                'description' => 'Another description'
33
            ),
34
            $csvReader->getRow(2)
35
        );
36
    }
37
38
    public function testReadCsvFileWithoutColumnHeaders()
39
    {
40
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_no_column_headers.csv');
41
        $csvReader = new CsvReader($file);
42
43
        $this->assertEmpty($csvReader->getColumnHeaders());
44
    }
45
46
    public function testReadCsvFileWithManualColumnHeaders()
47
    {
48
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_no_column_headers.csv');
49
        $csvReader = new CsvReader($file);
50
        $csvReader->setColumnHeaders(array('id', 'number', 'description'));
51
52
        foreach ($csvReader as $row) {
53
            $this->assertNotNull($row['id']);
54
            $this->assertNotNull($row['number']);
55
            $this->assertNotNull($row['description']);
56
        }
57
    }
58
59
    public function testReadCsvFileWithTrailingBlankLines()
60
    {
61
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_blank_lines.csv');
62
        $csvReader = new CsvReader($file);
63
        $csvReader->setColumnHeaders(array('id', 'number', 'description'));
64
65
        foreach ($csvReader as $row) {
66
            $this->assertNotNull($row['id']);
67
            $this->assertNotNull($row['number']);
68
            $this->assertNotNull($row['description']);
69
        }
70
    }
71
72
    public function testCountWithoutHeaders()
73
    {
74
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_no_column_headers.csv');
75
        $csvReader = new CsvReader($file);
76
        $this->assertEquals(3, $csvReader->count());
77
    }
78
79
    public function testCountWithHeaders()
80
    {
81
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_column_headers.csv');
82
        $csvReader = new CsvReader($file);
83
        $csvReader->setHeaderRowNumber(0);
84
        $this->assertEquals(3, $csvReader->count(), 'Row count should not include header');
85
    }
86
87
    public function testCountWithFewerElementsThanColumnHeadersNotStrict()
88
    {
89
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_fewer_elements_than_column_headers.csv');
90
        $csvReader = new CsvReader($file);
91
        $csvReader->setStrict(false);
92
        $csvReader->setHeaderRowNumber(0);
93
94
        $this->assertEquals(3, $csvReader->count());
95
    }
96
97
    public function testCountWithMoreElementsThanColumnHeadersNotStrict()
98
    {
99
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_more_elements_than_column_headers.csv');
100
        $csvReader = new CsvReader($file);
101
        $csvReader->setStrict(false);
102
        $csvReader->setHeaderRowNumber(0);
103
104
        $this->assertEquals(3, $csvReader->count());
105
        $this->assertFalse($csvReader->hasErrors());
106
        $this->assertEquals(array(6, 456, 'Another description'), array_values($csvReader->getRow(2)));
107
    }
108
109
    public function testCountDoesNotMoveFilePointer()
110
    {
111
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_column_headers.csv');
112
        $csvReader = new CsvReader($file);
113
        $csvReader->setHeaderRowNumber(0);
114
115
        $key_before_count = $csvReader->key();
116
        $csvReader->count();
117
        $key_after_count = $csvReader->key();
118
119
        $this->assertEquals($key_after_count, $key_before_count);
120
    }
121
122
    public function testVaryingElementCountWithColumnHeadersNotStrict()
123
    {
124
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_column_headers_varying_element_count.csv');
125
        $csvReader = new CsvReader($file);
126
        $csvReader->setStrict(false);
127
        $csvReader->setHeaderRowNumber(0);
128
129
        $this->assertEquals(4, $csvReader->count());
130
        $this->assertFalse($csvReader->hasErrors());
131
    }
132
133
    public function testVaryingElementCountWithoutColumnHeadersNotStrict()
134
    {
135
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_no_column_headers_varying_element_count.csv');
136
        $csvReader = new CsvReader($file);
137
        $csvReader->setStrict(false);
138
        $csvReader->setColumnHeaders(array('id', 'number', 'description'));
139
140
        $this->assertEquals(5, $csvReader->count());
141
        $this->assertFalse($csvReader->hasErrors());
142
    }
143
144
    public function testInvalidCsv()
145
    {
146
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_column_headers_varying_element_count.csv');
147
        $reader = new CsvReader($file);
148
        $reader->setHeaderRowNumber(0);
149
150
        $this->assertTrue($reader->hasErrors());
151
152
        $this->assertCount(2, $reader->getErrors());
153
154
        $errors = $reader->getErrors();
155
        $this->assertEquals(2, key($errors));
156
        $this->assertEquals(array('123', 'test'), current($errors));
157
158
        next($errors);
159
        $this->assertEquals(3, key($errors));
160
        $this->assertEquals(array('7', '7890', 'Some more info', 'too many columns'), current($errors));
161
    }
162
163
    public function testLastRowInvalidCsv()
164
    {
165
        $file = new \SplFileObject(__DIR__.'/../Fixtures/data_no_column_headers_varying_element_count.csv');
166
        $reader = new CsvReader($file);
167
        $reader->setColumnHeaders(array('id', 'number', 'description'));
168
169
        $this->assertTrue($reader->hasErrors());
170
        $this->assertCount(3, $reader->getErrors());
171
172
        $errors = $reader->getErrors();
173
        $this->assertEquals(1, key($errors));
174
        $this->assertEquals(array('6', 'strictly invalid'), current($errors));
175
176
        next($errors);
177
        $this->assertEquals(3, key($errors));
178
        $this->assertEquals(array('3','230','Yet more info','Even more info'), current($errors));
179
180
        next($errors);
181
        $this->assertEquals(4, key($errors));
182
        $this->assertEquals(array('strictly invalid'), current($errors));
183
    }
184
185
    public function testLineBreaks()
186
    {
187
        $reader = $this->getReader('data_cr_breaks.csv');
188
        $this->assertCount(3, $reader);
189
    }
190
191
    /**
192
     * @expectedException \Ddeboer\DataImport\Exception\DuplicateHeadersException description
193
     */
194
    public function testDuplicateHeadersThrowsException()
195
    {
196
        $reader = $this->getReader('data_column_headers_duplicates.csv');
197
        $reader->setHeaderRowNumber(0);
198
    }
199
200
    public function testDuplicateHeadersIncrement()
201
    {
202
        $reader = $this->getReader('data_column_headers_duplicates.csv');
203
        $reader->setHeaderRowNumber(0, CsvReader::DUPLICATE_HEADERS_INCREMENT);
204
        $reader->rewind();
205
        $current = $reader->current();
206
207
        $this->assertEquals(
208
            array('id', 'description', 'description1', 'description2', 'details', 'details1', 'last', 'UNKNOWN', 'UNKNOWN1'),
209
            $reader->getColumnHeaders()
210
        );
211
212
        $this->assertEquals(
213
            array(
214
                'id'           => '50',
215
                'description'  => 'First',
216
                'description1' => 'Second',
217
                'description2' => 'Third',
218
                'details'      => 'Details1',
219
                'details1'     => 'Details2',
220
                'last'         => 'Last one',
221
                'UNKNOWN'      => 'empty1',
222
                'UNKNOWN1'     => 'empty2'
223
            ),
224
            $current
225
        );
226
    }
227
228
    public function testDuplicateHeadersMerge()
229
    {
230
        $reader = $this->getReader('data_column_headers_duplicates.csv');
231
        $reader->setHeaderRowNumber(0, CsvReader::DUPLICATE_HEADERS_MERGE);
232
        $reader->rewind();
233
        $current = $reader->current();
234
235
        $this->assertCount(5, $reader->getColumnHeaders());
236
237
        $expected = array(
238
            'id'          => '50',
239
            'description' => array('First', 'Second', 'Third'),
240
            'details'     => array('Details1', 'Details2'),
241
            'last'        => 'Last one',
242
            ''            => array('empty1', 'empty2')
243
        );
244
        $this->assertEquals($expected, $current);
245
    }
246
247
    public function testMaximumNesting()
248
    {
249
        if (!function_exists('xdebug_is_enabled')) {
250
            $this->markTestSkipped('xDebug is not installed');
251
        }
252
253
        $xdebug_start = !xdebug_is_enabled();
254
        if ($xdebug_start) {
255
            xdebug_enable();
256
        }
257
258
        ini_set('xdebug.max_nesting_level', 200);
259
260
        $file = new \SplTempFileObject();
261
        for($i = 0; $i < 500; $i++) {
262
            $file->fwrite("1,2,3\n");
263
        }
264
265
        $reader = new CsvReader($file);
266
        $reader->rewind();
267
        $reader->setStrict(true);
268
        $reader->setColumnHeaders(array('one','two'));
269
270
        $current = $reader->current();
271
        $this->assertEquals(null, $current);
272
273
        if ($xdebug_start) {
274
            xdebug_disable();
275
        }
276
    }
277
278
    protected function getReader($filename)
279
    {
280
        $file = new \SplFileObject(__DIR__.'/../Fixtures/'.$filename);
281
282
        return new CsvReader($file);
283
    }
284
}
285