CsvParserTest::testParse()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 3
1
<?php
2
/**
3
 * This file is part of graze/data-file
4
 *
5
 * Copyright (c) 2016 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/data-file/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/data-file
12
 */
13
14
namespace Graze\DataFile\Test\Unit\Format\Parser;
15
16
use Graze\CsvToken\Csv\Bom;
17
use Graze\DataFile\Format\CsvFormat;
18
use Graze\DataFile\Format\CsvFormatInterface;
19
use Graze\DataFile\Format\Parser\CsvParser;
20
use Graze\DataFile\Test\Helper\CreateStreamTrait;
21
use Graze\DataFile\Test\TestCase;
22
use Mockery as m;
23
use RuntimeException;
24
25
class CsvParserTest extends TestCase
26
{
27
    use CreateStreamTrait;
28
29
    /**
30
     * @dataProvider parseLineData
31
     *
32
     * @param CsvFormatInterface $format
33
     * @param string             $line
34
     * @param array              $expected
35
     */
36
    public function testParse(CsvFormatInterface $format, $line, array $expected)
37
    {
38
        $parser = new CsvParser($format);
39
40
        $iterator = $parser->parse($this->createStream($line));
41
        $actual = iterator_to_array($iterator);
42
        $actual = array_values($actual);
43
44
        static::assertEquals($expected, $actual);
45
    }
46
47
    /**
48
     * @return array
49
     */
50
    public function parseLineData()
51
    {
52
        return [
53
            [
54
                new CsvFormat([CsvFormat::OPTION_HEADER_ROW => 0]),
55
                '"a","b",c,1,true,0.2,false,", enclosed","\\n \\r stuff",\\N',
56
                [['a', 'b', 'c', '1', 'true', '0.2', 'false', ', enclosed', "n r stuff", null]],
57
            ],
58
            [
59
                new CsvFormat([
60
                    CsvFormat::OPTION_DELIMITER    => '|',
61
                    CsvFormat::OPTION_ESCAPE       => '~',
62
                    CsvFormat::OPTION_QUOTE        => '`',
63
                    CsvFormat::OPTION_NULL         => 'null',
64
                    CsvFormat::OPTION_HEADER_ROW   => 0,
65
                    CsvFormat::OPTION_DOUBLE_QUOTE => true,
66
                ]),
67
                '`string`|`other,thing`|some stuff|escaped ~\\n|``` all the `` quotes `|null',
68
                [['string', 'other,thing', 'some stuff', 'escaped \n', '` all the ` quotes ', null]],
69
            ],
70
            [
71
                new CsvFormat([
72
                    CsvFormat::OPTION_QUOTE      => "\\",
73
                    CsvFormat::OPTION_DELIMITER  => '|',
74
                    CsvFormat::OPTION_ESCAPE     => "\\",
75
                    CsvFormat::OPTION_HEADER_ROW => 0,
76
                ]),
77
                'a|b|c|d\\|e',
78
                [['a', 'b', 'c', 'd|e']],
79
            ],
80
            [
81
                new CsvFormat([
82
                    CsvFormat::OPTION_HEADER_ROW   => 1,
83
                    CsvFormat::OPTION_DOUBLE_QUOTE => true,
84
                ]),
85
                file_get_contents(__DIR__ . '/../../../fixtures/csv_file.csv'),
86
                [
87
                    [
88
                        'id'     => '0',
89
                        'name'   => 'my name',
90
                        'things' => 'i like " quotes',
91
                        'stuff'  => 'question?',
92
                    ],
93
                    [
94
                        'id'     => '1',
95
                        'name'   => 'your name',
96
                        'things' => 'potatoes! ' . "\n" . 'and stuff',
97
                        'stuff'  => 'think',
98
                    ],
99
                    [
100
                        'id'     => '2',
101
                        'name'   => 'your , nice',
102
                        'things' => 'fish"',
103
                        'stuff'  => '","',
104
                    ],
105
                ],
106
            ],
107
            [
108
                new CsvFormat([
109
                    CsvFormat::OPTION_DATA_START   => 1,
110
                    CsvFormat::OPTION_LIMIT        => 2,
111
                    CsvFormat::OPTION_DOUBLE_QUOTE => true,
112
                ]),
113
                file_get_contents(__DIR__ . '/../../../fixtures/csv_file.csv'),
114
                [
115
                    ['id', 'name', 'things', 'stuff'],
116
                    ['0', 'my name', 'i like " quotes', 'question?'],
117
                ],
118
            ],
119
            [
120
                new CsvFormat([
121
                    CsvFormat::OPTION_DATA_START   => 4,
122
                    CsvFormat::OPTION_DOUBLE_QUOTE => true,
123
                ]),
124
                file_get_contents(__DIR__ . '/../../../fixtures/csv_file.csv'),
125
                [
126
                    ['2', 'your , nice', 'fish"', '","'],
127
                ],
128
            ],
129
            [
130
                new CsvFormat([
131
                    CsvFormat::OPTION_HEADER_ROW => 1,
132
                ]),
133
                "\n" . '"1","2","3","4","5"',
134
                [
135
                    ['1', '2', '3', '4', '5'],
136
                ],
137
            ],
138
            [
139
                new CsvFormat([
140
                    CsvFormat::OPTION_BOM => Bom::BOM_UTF8,
141
                ]),
142
                Bom::BOM_UTF8 . '"text","here",",there"',
143
                [['text', 'here', ',there']],
144
            ],
145
        ];
146
    }
147
148
    /**
149
     * @dataProvider parseFailureData
150
     *
151
     * @param CsvFormatInterface $format
152
     * @param string             $line
153
     * @param string             $expected
154
     */
155
    public function testParseFailure(CsvFormatInterface $format, $line, $expected)
156
    {
157
        $parser = new CsvParser($format);
158
159
        $iterator = $parser->parse($this->createStream($line));
160
161
        static::expectException($expected);
162
        $actual = iterator_to_array($iterator);
163
        $actual = array_values(array_map('iterator_to_array', $actual));
164
165
        static::assertEquals($expected, $actual);
166
    }
167
168
    /**
169
     * @return array
170
     */
171
    public function parseFailureData()
172
    {
173
        return [
174
            [
175
                new CsvFormat([
176
                    CsvFormat::OPTION_HEADER_ROW   => 1,
177
                    CsvFormat::OPTION_DOUBLE_QUOTE => true,
178
                ]),
179
                '"id","fish","cake"' . "\n" . '"1","name","thing","too many"',
180
                RuntimeException::class,
181
            ],
182
        ];
183
    }
184
}
185