Completed
Pull Request — master (#31)
by Chad
01:21
created

ReaderTest   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 260
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 15
c 1
b 0
f 0
lcom 2
cbo 4
dl 0
loc 260
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 6 1
A tearDown() 0 4 1
B basicUsage() 0 36 2
A constructInvalidFileParam() 0 4 1
A getFiles() 0 9 1
A consecutiveRewind() 0 12 2
A emptyFiles() 0 12 2
B readNoHeaders() 0 37 2
A getReaders() 0 23 1
A current() 0 16 1
A getEmptyFiles() 0 9 1
1
<?php
2
namespace SubjectivePHPTest\Csv;
3
4
use SubjectivePHP\Csv\CsvOptions;
5
use SubjectivePHP\Csv\HeaderStrategy;
6
use SubjectivePHP\Csv\Reader;
7
use PHPUnit\Framework\TestCase;
8
9
/**
10
 * Unit tests for the SubjectivePHP\Csv\Reader class
11
 *
12
 * @coversDefaultClass \SubjectivePHP\Csv\Reader
13
 * @covers ::__construct
14
 * @covers ::__destruct
15
 * @covers ::<private>
16
 */
17
final class ReaderTest extends TestCase
18
{
19
    private $unreadableFilePath;
20
21
    public function setUp()
22
    {
23
        $this->unreadableFilePath = tempnam(sys_get_temp_dir(), 'csv');
24
        touch($this->unreadableFilePath);
25
        chmod($this->unreadableFilePath, 0220);
26
    }
27
28
    public function tearDown()
29
    {
30
        unlink($this->unreadableFilePath);
31
    }
32
33
    /**
34
     * Verify basic usage of Reader.
35
     *
36
     * @test
37
     * @covers ::next
38
     * @covers ::current
39
     * @covers ::key
40
     * @covers ::valid
41
     * @covers ::rewind
42
     * @dataProvider getReaders()
43
     *
44
     * @param Reader $reader The Reader instance to use in the test.
45
     *
46
     * @return void
47
     */
48
    public function basicUsage(Reader $reader)
49
    {
50
        $expected = [
51
            [
52
                'id' => 'bk101',
53
                'author' => 'Gambardella, Matthew',
54
                'title' => 'XML Developer\'s Guide',
55
                'genre' => 'Computer',
56
                'price' => '44.95',
57
                'publish_date' => '2000-10-01',
58
                'description' => 'An in-depth look at creating applications with XML.',
59
            ],
60
            [
61
                'id' => 'bk102',
62
                'author' => 'Ralls, Kim',
63
                'title' => 'Midnight Rain',
64
                'genre' => 'Fantasy',
65
                'price' => '5.95',
66
                'publish_date' => '2000-12-16',
67
                'description' => 'A former architect battles corporate zombies and an evil sorceress.',
68
            ],
69
            [
70
                'id' => 'bk103',
71
                'author' => 'Corets, Eva',
72
                'title' => 'Maeve Ascendant',
73
                'genre' => 'Fantasy',
74
                'price' => '5.95',
75
                'publish_date' => '2000-11-17',
76
                'description' => 'Young survivors lay the foundation for a new society in England.',
77
            ],
78
        ];
79
80
        foreach ($reader as $key => $row) {
81
            $this->assertSame($expected[$key], $row);
82
        }
83
    }
84
85
    /**
86
     * @test
87
     */
88
    public function readNoHeaders()
89
    {
90
        $expected = [
91
            [
92
                'bk101',
93
                'Gambardella, Matthew',
94
                'XML Developer\'s Guide',
95
                'Computer',
96
                '44.95',
97
                '2000-10-01',
98
                'An in-depth look at creating applications with XML.',
99
            ],
100
            [
101
                'bk102',
102
                'Ralls, Kim',
103
                'Midnight Rain',
104
                'Fantasy',
105
                '5.95',
106
                '2000-12-16',
107
                'A former architect battles corporate zombies and an evil sorceress.',
108
            ],
109
            [
110
                'bk103',
111
                'Corets, Eva',
112
                'Maeve Ascendant',
113
                'Fantasy',
114
                '5.95',
115
                '2000-11-17',
116
                'Young survivors lay the foundation for a new society in England.',
117
            ],
118
        ];
119
120
        $reader = new Reader(__DIR__ . '/_files/no_headers.csv', HeaderStrategy::none());
121
        foreach ($reader as $key => $row) {
122
            $this->assertSame($expected[$key], $row);
123
        }
124
    }
125
126
    /**
127
     * Data provider for basic usage test
128
     *
129
     * @return array
130
     */
131
    public function getReaders()
132
    {
133
        $headers = ['id', 'author', 'title', 'genre', 'price', 'publish_date', 'description'];
134
        return [
135
            [new Reader(__DIR__ . '/_files/basic.csv')],
136
            [new Reader(__DIR__ . '/_files/basic.csv', HeaderStrategy::provide($headers))],
137
            [new Reader(__DIR__ . '/_files/no_headers.csv', HeaderStrategy::provide($headers))],
138
            [
139
                new Reader(
140
                    __DIR__ . '/_files/pipe_delimited.txt',
141
                    HeaderStrategy::provide($headers),
142
                    new CsvOptions('|')
143
                )
144
            ],
145
            [
146
                new Reader(
147
                    __DIR__ . '/_files/tab_delimited.txt',
148
                    HeaderStrategy::provide($headers),
149
                    new CsvOptions("\t")
150
                )
151
            ],
152
        ];
153
    }
154
155
    /**
156
     * Verify parameter checks for $file in __construct().
157
     *
158
     * @param mixed $file The file parameter to check.
159
     *
160
     * @test
161
     * @covers ::__construct
162
     * @expectedException \InvalidArgumentException
163
     * @expectedExceptionMessage $file must be a string containing a full path to a readable delimited file
164
     * @dataProvider getFiles
165
     *
166
     * @return void
167
     */
168
    public function constructInvalidFileParam($file)
169
    {
170
        $reader = new Reader($file);
0 ignored issues
show
Unused Code introduced by
$reader is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
171
    }
172
173
    /**
174
     * Data provider for constructInvalidFileParam() test.
175
     *
176
     * @return array
177
     */
178
    public function getFiles()
179
    {
180
        return [
181
            [__DIR__ . '/_files/not_readable.csv'],
182
            [true],
183
            [null],
184
            [__DIR__ . '/_files/doesnotexist.csv'],
185
        ];
186
    }
187
188
    /**
189
     * Verify behaviour of consecutive rewind().
190
     *
191
     * @test
192
     * @covers ::rewind
193
     *
194
     * @return void
195
     */
196
    public function consecutiveRewind()
197
    {
198
        $reader = new Reader(__DIR__ . '/_files/basic.csv');
199
        $count = 0;
200
        foreach ($reader as $row) {
201
            $count++;
202
        }
203
204
        $reader->rewind();
205
        $reader->rewind();
206
        $this->assertSame(0, $reader->key());
207
    }
208
209
    /**
210
     * Verify basic behaviour of current().
211
     *
212
     * @test
213
     * @covers ::current
214
     *
215
     * @return void
216
     */
217
    public function current()
218
    {
219
        $reader = new Reader(__DIR__ . '/_files/basic.csv');
220
        $this->assertSame(
221
            [
222
                'id' => 'bk101',
223
                'author' => 'Gambardella, Matthew',
224
                'title' => 'XML Developer\'s Guide',
225
                'genre' => 'Computer',
226
                'price' => '44.95',
227
                'publish_date' => '2000-10-01',
228
                'description' => 'An in-depth look at creating applications with XML.',
229
            ],
230
            $reader->current()
231
        );
232
    }
233
234
    /**
235
     * Verify behavior of Reader with an empty file
236
     *
237
     * @test
238
     * @covers ::next
239
     * @covers ::current
240
     * @covers ::key
241
     * @covers ::valid
242
     * @covers ::rewind
243
     * @dataProvider getEmptyFiles
244
     *
245
     * @param Reader $reader The reader instance to use in the tests.
246
     *
247
     * @return void
248
     */
249
    public function emptyFiles(Reader $reader)
250
    {
251
        $total = 0;
252
253
        $reader->rewind();
254
        while ($reader->valid()) {
255
            $total++;
256
            $reader->next();
257
        }
258
259
        $this->assertSame(0, $total);
260
    }
261
262
    /**
263
     * Data provider for empty file test.
264
     *
265
     * @return array
266
     */
267
    public function getEmptyFiles()
268
    {
269
        $headers = ['id', 'author', 'title', 'genre', 'price', 'publish_date', 'description'];
270
        return [
271
            [new Reader(__DIR__ . '/_files/empty.csv')],
272
            [new Reader(__DIR__ . '/_files/headers_only.csv')],
273
            [new Reader(__DIR__ . '/_files/headers_only.csv', HeaderStrategy::provide($headers))],
274
        ];
275
    }
276
}
277