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

ReaderTest::readWithCustomHeaders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 47
rs 9.0303
c 1
b 0
f 0
cc 1
eloc 33
nc 1
nop 0
1
<?php
2
namespace SubjectivePHPTest\Csv;
3
4
use SubjectivePHP\Csv\CsvOptions;
5
use SubjectivePHP\Csv\DeriveHeaderStrategy;
6
use SubjectivePHP\Csv\MappedHeaderStrategy;
7
use SubjectivePHP\Csv\NoHeaderStrategy;
8
use SubjectivePHP\Csv\ProvidedHeaderStrategy;
9
use SubjectivePHP\Csv\Reader;
10
use PHPUnit\Framework\TestCase;
11
12
/**
13
 * Unit tests for the SubjectivePHP\Csv\Reader class
14
 *
15
 * @coversDefaultClass \SubjectivePHP\Csv\Reader
16
 * @covers ::__construct
17
 * @covers ::__destruct
18
 * @covers ::<private>
19
 */
20
final class ReaderTest extends TestCase
21
{
22
    /**
23
     * Verify basic usage of Reader.
24
     *
25
     * @test
26
     * @covers ::getIterator
27
     * @dataProvider getReaders()
28
     *
29
     * @param Reader $reader The Reader instance to use in the test.
30
     *
31
     * @return void
32
     */
33
    public function basicUsage(Reader $reader)
34
    {
35
        $expected = [
36
            [
37
                'id' => 'bk101',
38
                'author' => 'Gambardella, Matthew',
39
                'title' => 'XML Developer\'s Guide',
40
                'genre' => 'Computer',
41
                'price' => '44.95',
42
                'publish_date' => '2000-10-01',
43
                'description' => 'An in-depth look at creating applications with XML.',
44
            ],
45
            [
46
                'id' => 'bk102',
47
                'author' => 'Ralls, Kim',
48
                'title' => 'Midnight Rain',
49
                'genre' => 'Fantasy',
50
                'price' => '5.95',
51
                'publish_date' => '2000-12-16',
52
                'description' => 'A former architect battles corporate zombies and an evil sorceress.',
53
            ],
54
            [
55
                'id' => 'bk103',
56
                'author' => 'Corets, Eva',
57
                'title' => 'Maeve Ascendant',
58
                'genre' => 'Fantasy',
59
                'price' => '5.95',
60
                'publish_date' => '2000-11-17',
61
                'description' => 'Young survivors lay the foundation for a new society in England.',
62
            ],
63
        ];
64
65
        $this->assertSame($expected, array_values(iterator_to_array($reader)));
66
    }
67
68
    /**
69
     * @test
70
     * @covers ::getIterator
71
     */
72
    public function readWithCustomHeaders()
73
    {
74
        $expected = [
75
            [
76
                'Book ID' => 'bk101',
77
                'Author' => 'Gambardella, Matthew',
78
                'Title' => 'XML Developer\'s Guide',
79
                'Genre' => 'Computer',
80
                'Price' => '44.95',
81
                'Publish Date' => '2000-10-01',
82
                'Description' => 'An in-depth look at creating applications with XML.',
83
            ],
84
            [
85
                'Book ID' => 'bk102',
86
                'Author' => 'Ralls, Kim',
87
                'Title' => 'Midnight Rain',
88
                'Genre' => 'Fantasy',
89
                'Price' => '5.95',
90
                'Publish Date' => '2000-12-16',
91
                'Description' => 'A former architect battles corporate zombies and an evil sorceress.',
92
            ],
93
            [
94
                'Book ID' => 'bk103',
95
                'Author' => 'Corets, Eva',
96
                'Title' => 'Maeve Ascendant',
97
                'Genre' => 'Fantasy',
98
                'Price' => '5.95',
99
                'Publish Date' => '2000-11-17',
100
                'Description' => 'Young survivors lay the foundation for a new society in England.',
101
            ],
102
        ];
103
104
        $strategy = new MappedHeaderStrategy(
105
            [
106
                'id' => 'Book ID',
107
                'author' => 'Author',
108
                'title' => 'Title',
109
                'genre' => 'Genre',
110
                'price' => 'Price',
111
                'publish_date' => 'Publish Date',
112
                'description' => 'Description',
113
            ]
114
        );
115
116
        $reader = new Reader(__DIR__ . '/_files/basic.csv', $strategy);
117
        $this->assertSame($expected, array_values(iterator_to_array($reader)));
118
    }
119
120
    /**
121
     * @test
122
     * @covers ::getIterator
123
     */
124
    public function readNoHeaders()
125
    {
126
        $expected = [
127
            [
128
                'bk101',
129
                'Gambardella, Matthew',
130
                'XML Developer\'s Guide',
131
                'Computer',
132
                '44.95',
133
                '2000-10-01',
134
                'An in-depth look at creating applications with XML.',
135
            ],
136
            [
137
                'bk102',
138
                'Ralls, Kim',
139
                'Midnight Rain',
140
                'Fantasy',
141
                '5.95',
142
                '2000-12-16',
143
                'A former architect battles corporate zombies and an evil sorceress.',
144
            ],
145
            [
146
                'bk103',
147
                'Corets, Eva',
148
                'Maeve Ascendant',
149
                'Fantasy',
150
                '5.95',
151
                '2000-11-17',
152
                'Young survivors lay the foundation for a new society in England.',
153
            ],
154
        ];
155
156
        $reader = new Reader(__DIR__ . '/_files/no_headers.csv', new NoHeaderStrategy());
157
        $this->assertSame($expected, array_values(iterator_to_array($reader)));
158
    }
159
160
    /**
161
     * Data provider for basic usage test
162
     *
163
     * @return array
164
     */
165
    public function getReaders()
166
    {
167
        $headers = ['id', 'author', 'title', 'genre', 'price', 'publish_date', 'description'];
168
        return [
169
            [new Reader(__DIR__ . '/_files/basic.csv')],
170
            [new Reader(__DIR__ . '/_files/basic.csv', new ProvidedHeaderStrategy($headers))],
171
            [new Reader(__DIR__ . '/_files/no_headers.csv', new ProvidedHeaderStrategy($headers))],
172
            [
173
                new Reader(
174
                    __DIR__ . '/_files/pipe_delimited.txt',
175
                    new ProvidedHeaderStrategy($headers),
176
                    new CsvOptions('|')
177
                )
178
            ],
179
            [
180
                new Reader(
181
                    __DIR__ . '/_files/tab_delimited.txt',
182
                    new ProvidedHeaderStrategy($headers),
183
                    new CsvOptions("\t")
184
                )
185
            ],
186
        ];
187
    }
188
189
    /**
190
     * Verify parameter checks for $file in __construct().
191
     *
192
     * @param mixed $file The file parameter to check.
0 ignored issues
show
Bug introduced by
There is no parameter named $file. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
193
     *
194
     * @test
195
     * @covers ::__construct
196
     * @expectedException \InvalidArgumentException
197
     * @expectedExceptionMessage $file must be a string containing a full path to a readable delimited file
198
     *
199
     * @return void
200
     */
201
    public function constructWithFileThatDoesNotExist()
202
    {
203
        new Reader(__DIR__ . '/_files/not_found.csv');
204
    }
205
206
    /**
207
     * @test
208
     * @covers ::__construct
209
     */
210
    public function constructWithUnreadableFile()
211
    {
212
        try {
213
            $unreadableFilePath = tempnam(sys_get_temp_dir(), 'csv');
214
            touch($unreadableFilePath);
215
            chmod($unreadableFilePath, 0220);
216
            new Reader($unreadableFilePath);
217
        } catch (\InvalidArgumentException $e) {
218
            $this->assertSame(
219
                '$file must be a string containing a full path to a readable delimited file',
220
                $e->getMessage()
221
            );
222
        } finally {
223
            unlink($unreadableFilePath);
224
        }
225
    }
226
227
    /**
228
     * Verify behavior of Reader with an empty file
229
     *
230
     * @test
231
     * @covers ::getIterator
232
     * @dataProvider getEmptyFiles
233
     *
234
     * @param Reader $reader The reader instance to use in the tests.
235
     *
236
     * @return void
237
     */
238
    public function emptyFiles(Reader $reader)
239
    {
240
        $total = 0;
241
242
        foreach ($reader as $row) {
243
            $total++;
244
        }
245
246
        $this->assertSame(0, $total);
247
    }
248
249
    /**
250
     * Data provider for empty file test.
251
     *
252
     * @return array
253
     */
254
    public function getEmptyFiles()
255
    {
256
        $headers = ['id', 'author', 'title', 'genre', 'price', 'publish_date', 'description'];
257
        return [
258
            [new Reader(__DIR__ . '/_files/empty.csv')],
259
            [new Reader(__DIR__ . '/_files/headers_only.csv')],
260
            [new Reader(__DIR__ . '/_files/headers_only.csv', new ProvidedHeaderStrategy($headers))],
261
        ];
262
    }
263
}
264