1<?php
2
3namespace dokuwiki\plugin\csv\test;
4
5use DokuWikiTest;
6
7/**
8 * @group plugin_csv
9 * @group plugins
10 */
11class CSVTest extends DokuWikiTest
12{
13
14    private $delimiters = array(
15        'c' => ',',
16        's' => ';',
17        't' => "\t",
18    );
19
20    private $enclosings = array(
21        'q' => '"',
22        's' => "'",
23    );
24
25    private $escapes = array(
26        'q' => '"',
27        'b' => '\\',
28    );
29
30    /**
31     * @return \Generator
32     * @see testParser
33     */
34    public function provideCSVFiles()
35    {
36        // run through all the test files
37        $files = glob(__DIR__ . '/csv/*.csv');
38        foreach ($files as $file) {
39            // load test csv and json files
40            $csvdata = file_get_contents($file);
41            $file = basename($file, '.csv');
42            $json = file_get_contents(__DIR__ . '/json/' . $file . '.json');
43            $expect = json_decode($json, true);
44
45            // get delimiter configs form file name
46            list($delim, $enc, $esc) = explode('-', $file);
47            $delim = $this->delimiters[$delim];
48            $enc = $this->enclosings[$enc];
49            $esc = $this->escapes[$esc];
50
51            yield [$file, $expect, $csvdata, $delim, $enc, $esc];
52        }
53    }
54
55    /**
56     * @dataProvider provideCSVFiles
57     * @param string $file
58     * @param string[][] $expect
59     * @param string $csvdata
60     * @param string $delim
61     * @param string $enc
62     * @param string $esc
63     */
64    public function testParser($file, $expect, $csvdata, $delim, $enc, $esc)
65    {
66        // read all data
67        $result = [];
68        while ($csvdata != '') {
69            $line = \helper_plugin_csv::csv_explode_row($csvdata, $delim, $enc, $esc);
70            if ($line !== false) array_push($result, $line);
71        }
72
73        $this->assertEquals($expect, $result, $file);
74    }
75
76    /**
77     * check general content loading
78     */
79    public function testContent()
80    {
81        $contents = file_get_contents(__DIR__ . '/avengers.csv');
82
83        $opt = \helper_plugin_csv::getDefaultOpt();
84
85        $data = \helper_plugin_csv::prepareData($contents, $opt);
86        $this->assertSame(174, count($data), 'number of rows');
87        $this->assertSame(21, count($data[0]), 'number of columns');
88    }
89
90    /**
91     * check general content loading
92     */
93    public function testFilter()
94    {
95        $contents = file_get_contents(__DIR__ . '/avengers.csv');
96
97        $opt = \helper_plugin_csv::getDefaultOpt();
98        $opt['filter'][4] = '^FEMALE$';
99
100        $data = \helper_plugin_csv::prepareData($contents, $opt);
101        $this->assertSame(59, count($data), 'number of rows');
102        $this->assertSame(21, count($data[0]), 'number of columns');
103
104        $opt['filter'][1] = '^.*?jessica.*?$';
105        $data = \helper_plugin_csv::prepareData($contents, $opt);
106        $this->assertSame(3, count($data), 'number of rows');
107        $this->assertSame(21, count($data[0]), 'number of columns');
108
109        $this->assertEquals('Jessica Jones', $data[2][1]);
110    }
111
112    /**
113     * @return array[]
114     * @see testOptions
115     */
116    public function provideOptions()
117    {
118        return [
119            ['https://example.com/file.csv', ['file' => 'https://example.com/file.csv']],
120            ['foo.csv', ['file' => 'foo.csv']],
121            ['file=foo.csv', ['file' => 'foo.csv']],
122            ['file="foo.csv"', ['file' => 'foo.csv']],
123            ['delim=tab', ['delim' => "\t"]],
124            ['filter[2]="*t(es)t*"', ['filter' => [1 => '^.*?t\(es\)t.*?$']]],
125            ['filter[2][r]="t(es)t.*"', ['filter' => [1 => 't(es)t.*']]],
126            ['foo="with spaces"', ['foo' => 'with spaces']],
127            ['output=4,3', ['outc' => 3, 'outr' => 2]],
128            ['output=4', ['outc' => 3, 'outr' => 0]],
129        ];
130    }
131
132    /**
133     * check the option parsing
134     *
135     * @dataProvider provideOptions
136     * @param string $input
137     * @param string[] $expect
138     * @return void
139     */
140    public function testOptions($input, $expect)
141    {
142        $opt = \helper_plugin_csv::getDefaultOpt();
143        unset($opt['output']);
144
145        $expect = array_merge($opt, $expect);
146        $result = \helper_plugin_csv::parseOptions($input);
147
148        $this->assertEquals($expect, $result);
149    }
150
151}
152