CsvReaderTest::testMaximumNesting()   B
last analyzed

Complexity

Conditions 5
Paths 16

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 30
rs 8.439
c 1
b 0
f 0
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'),
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
            ),
222
            $current
223
        );
224
    }
225
226
    public function testDuplicateHeadersMerge()
227
    {
228
        $reader = $this->getReader('data_column_headers_duplicates.csv');
229
        $reader->setHeaderRowNumber(0, CsvReader::DUPLICATE_HEADERS_MERGE);
230
        $reader->rewind();
231
        $current = $reader->current();
232
233
        $this->assertCount(4, $reader->getColumnHeaders());
234
235
        $expected = array(
236
            'id'          => '50',
237
            'description' => array('First', 'Second', 'Third'),
238
            'details'     => array('Details1', 'Details2'),
239
            'last'        => 'Last one'
240
        );
241
        $this->assertEquals($expected, $current);
242
    }
243
244
    public function testMaximumNesting()
245
    {
246
        if (!function_exists('xdebug_is_enabled')) {
247
            $this->markTestSkipped('xDebug is not installed');
248
        }
249
250
        $xdebug_start = !xdebug_is_enabled();
251
        if ($xdebug_start) {
252
            xdebug_enable();
253
        }
254
255
        ini_set('xdebug.max_nesting_level', 200);
256
257
        $file = new \SplTempFileObject();
258
        for($i = 0; $i < 500; $i++) {
259
            $file->fwrite("1,2,3\n");
260
        }
261
262
        $reader = new CsvReader($file);
263
        $reader->rewind();
264
        $reader->setStrict(true);
265
        $reader->setColumnHeaders(array('one','two'));
266
267
        $current = $reader->current();
268
        $this->assertEquals(null, $current);
269
270
        if ($xdebug_start) {
271
            xdebug_disable();
272
        }
273
    }
274
275
    protected function getReader($filename)
276
    {
277
        $file = new \SplFileObject(__DIR__.'/../Fixtures/'.$filename);
278
279
        return new CsvReader($file);
280
    }
281
}
282