Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Test phpunit_dataset features.
19
 *
20
 * @package    core
21
 * @category   tests
22
 * @copyright  2020 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
declare(strict_types=1);
27
 
28
namespace core;
29
 
30
use advanced_testcase;
31
use phpunit_dataset;
32
use org\bovigo\vfs\vfsStream;
33
 
34
/**
35
 * Test phpunit_dataset features.
36
 *
37
 * @coversDefaultClass \phpunit_dataset
38
 */
39
class phpunit_dataset_test extends advanced_testcase {
40
 
41
 
42
    /**
43
     * @covers ::from_files
44
     */
11 efrain 45
    public function test_from_files(): void {
1 efrain 46
 
47
        $ds = new phpunit_dataset();
48
 
49
        $files = [
50
            __DIR__ . '/fixtures/sample_dataset.xml',
51
            'user2' => __DIR__ . '/fixtures/sample_dataset.csv',
52
        ];
53
 
54
        // We need public properties to check the basis.
55
        $dsref = new \ReflectionClass($ds);
56
        $dstables = $dsref->getProperty('tables');
57
        $dscolumns = $dsref->getProperty('columns');
58
        $dsrows = $dsref->getProperty('rows');
59
 
60
        // Expectations.
61
        $exptables = ['user', 'user2'];
62
        $expcolumns = ['id', 'username', 'email'];
63
        $exprows = [
64
            ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
65
            ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
66
        ];
67
 
68
        $ds->from_files($files);
69
 
70
        $this->assertIsArray($dstables->getValue($ds));
71
        $this->assertSame($exptables, $dstables->getValue($ds));
72
        $this->assertIsArray($dscolumns->getValue($ds));
73
        $this->assertSame($expcolumns, $dscolumns->getValue($ds)['user']);
74
        $this->assertSame($expcolumns, $dscolumns->getValue($ds)['user2']);
75
        $this->assertIsArray($dsrows->getValue($ds));
76
        $this->assertEquals($exprows, $dsrows->getValue($ds)['user']); // Equals because of stringified integers on load.
77
        $this->assertEquals($exprows, $dsrows->getValue($ds)['user2']); // Equals because of stringified integers on load.
78
    }
79
 
80
    /**
81
     * test_from_file() data provider.
82
     */
83
    public function from_file_provider() {
84
        // Create an unreadable file with vfsStream.
85
        $vfsfile = vfsStream::newFile('unreadable', 0222);
86
        vfsStream::setup('root')->addChild($vfsfile);
87
 
88
        return [
89
            'file not found' => [
90
                'fullpath' => '/this/does/not/exist',
91
                'tablename' => 'user',
92
                'exception' => 'from_file, file not found: /this/does/not/exist',
93
                'tables' => [],
94
                'columns' => [],
95
                'rows' => [],
96
            ],
97
            'file not readable' => [
98
                'fullpath' => $vfsfile->url(),
99
                'tablename' => 'user',
100
                'exception' => 'from_file, file not readable: ' . $vfsfile->url(),
101
                'tables' => [],
102
                'columns' => [],
103
                'rows' => [],
104
            ],
105
            'wrong extension' => [
106
                'fullpath' => __DIR__ . '/fixtures/sample_dataset.txt',
107
                'tablename' => 'user',
108
                'exception' => 'from_file, cannot handle files with extension: txt',
109
                'tables' => [],
110
                'columns' => [],
111
                'rows' => [],
112
            ],
113
            'csv loads ok' => [
114
                'fullpath' => __DIR__ . '/fixtures/sample_dataset.csv',
115
                'tablename' => 'user',
116
                'exception' => null,
117
                'tables' => ['user'],
118
                'columns' => ['user' =>
119
                    ['id', 'username', 'email']
120
                ],
121
                'rows' => ['user' =>
122
                    [
123
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
124
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
125
                    ]
126
                ],
127
            ],
128
            'xml loads ok' => [
129
                'fullpath' => __DIR__ . '/fixtures/sample_dataset.xml',
130
                'tablename' => 'user',
131
                'exception' => null,
132
                'tables' => ['user'],
133
                'columns' => ['user' =>
134
                    ['id', 'username', 'email']
135
                ],
136
                'rows' => ['user' =>
137
                    [
138
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
139
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
140
                    ]
141
                ],
142
            ],
143
        ];
144
    }
145
 
146
    /**
147
     * @dataProvider from_file_provider
148
     * @covers ::from_file
149
     */
150
    public function test_from_file(string $fullpath, string $tablename, ?string $exception,
11 efrain 151
        array $tables, array $columns, array $rows): void {
1 efrain 152
 
153
        $ds = new phpunit_dataset();
154
 
155
        // We need public properties to check the basis.
156
        $dsref = new \ReflectionClass($ds);
157
        $dstables = $dsref->getProperty('tables');
158
        $dscolumns = $dsref->getProperty('columns');
159
        $dsrows = $dsref->getProperty('rows');
160
 
161
        // We are expecting an exception.
162
        if (!empty($exception)) {
163
            $this->expectException('coding_exception');
164
            $this->expectExceptionMessage($exception);
165
        }
166
 
167
        $ds->from_file($fullpath, $tablename);
168
 
169
        $this->assertIsArray($dstables->getValue($ds));
170
        $this->assertSame($tables, $dstables->getValue($ds));
171
        $this->assertIsArray($dscolumns->getValue($ds));
172
        $this->assertSame($columns, $dscolumns->getValue($ds));
173
        $this->assertIsArray($dsrows->getValue($ds));
174
        $this->assertEquals($rows, $dsrows->getValue($ds)); // Equals because of stringified integers on load.
175
    }
176
 
177
    /**
178
     * test_from_string() data provider.
179
     */
180
    public function from_string_provider() {
181
 
182
        return [
183
            'wrong type' => [
184
                'content' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.xml'),
185
                'type' => 'txt',
186
                'tablename' => 'user',
187
                'exception' => 'from_string, cannot handle contents of type: txt',
188
                'tables' => [],
189
                'columns' => [],
190
                'rows' => [],
191
            ],
192
            'missing cvs table' => [
193
                'content' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.csv'),
194
                'type' => 'csv',
195
                'tablename' => '',
196
                'exception' => 'from_string, contents of type "cvs" require a $table to be passed, none found',
197
                'tables' => [],
198
                'columns' => [],
199
                'rows' => [],
200
            ],
201
            'csv loads ok' => [
202
                'fullpath' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.csv'),
203
                'type' => 'csv',
204
                'tablename' => 'user',
205
                'exception' => null,
206
                'tables' => ['user'],
207
                'columns' => ['user' =>
208
                    ['id', 'username', 'email']
209
                ],
210
                'rows' => ['user' =>
211
                    [
212
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
213
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
214
                    ]
215
                ],
216
            ],
217
            'xml loads ok' => [
218
                'fullpath' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.xml'),
219
                'type' => 'xml',
220
                'tablename' => 'user',
221
                'exception' => null,
222
                'tables' => ['user'],
223
                'columns' => ['user' =>
224
                    ['id', 'username', 'email']
225
                ],
226
                'rows' => ['user' =>
227
                    [
228
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
229
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
230
                    ]
231
                ],
232
            ],
233
        ];
234
    }
235
 
236
    /**
237
     * @dataProvider from_string_provider
238
     * @covers ::from_string
239
     */
240
    public function test_from_string(string $content, string $type, string $tablename, ?string $exception,
11 efrain 241
        array $tables, array $columns, array $rows): void {
1 efrain 242
 
243
        $ds = new phpunit_dataset();
244
 
245
        // We need public properties to check the basis.
246
        $dsref = new \ReflectionClass($ds);
247
        $dstables = $dsref->getProperty('tables');
248
        $dscolumns = $dsref->getProperty('columns');
249
        $dsrows = $dsref->getProperty('rows');
250
 
251
        // We are expecting an exception.
252
        if (!empty($exception)) {
253
            $this->expectException('coding_exception');
254
            $this->expectExceptionMessage($exception);
255
        }
256
 
257
        $ds->from_string($content, $type, $tablename);
258
 
259
        $this->assertIsArray($dstables->getValue($ds));
260
        $this->assertSame($tables, $dstables->getValue($ds));
261
        $this->assertIsArray($dscolumns->getValue($ds));
262
        $this->assertSame($columns, $dscolumns->getValue($ds));
263
        $this->assertIsArray($dsrows->getValue($ds));
264
        $this->assertEquals($rows, $dsrows->getValue($ds)); // Equals because of stringified integers on load.
265
    }
266
 
267
    /**
268
     * test_from_array() data provider.
269
     */
270
    public function from_array_provider() {
271
        return [
272
            'repeated array table many structures' => [
273
                'structure' => [
274
                    'user' => [
275
                        ['id' => 5, 'name' => 'John'],
276
                        ['id' => 6, 'name' => 'Jane'],
277
                    ],
278
                ],
279
                'exception' => 'from_array, table already added to dataset: user',
280
                'tables' => [],
281
                'columns' => [],
282
                'rows' => [],
283
                'repeated' => true, // To force the table already exists exception.
284
            ],
285
            'wrong number of columns' => [
286
                'structure' => [
287
                    'user' => [
288
                        ['id' => 5, 'name' => 'John'],
289
                        ['id' => 6],
290
                    ],
291
                ],
292
                'exception' => 'from_array, number of columns must match number of values, found: 2 vs 1',
293
                'tables' => [],
294
                'columns' => [],
295
                'rows' => [],
296
            ],
297
            'wrong not matching names of columns' => [
298
                'structure' => [
299
                    'user' => [
300
                        ['id' => 5, 'name' => 'John'],
301
                        ['id' => 6, 'noname' => 'Jane'],
302
                    ],
303
                ],
304
                'exception' => 'from_array, columns in all elements must match first one, found: id, noname',
305
                'tables' => [],
306
                'columns' => [],
307
                'rows' => [],
308
            ],
309
            'ok non-associative format' => [
310
                'structure' => [
311
                    'user' => [
312
                        ['id', 'name'],
313
                        [5, 'John'],
314
                        [6, 'Jane'],
315
                    ],
316
                ],
317
                'exception' => null,
318
                'tables' => ['user'],
319
                'columns' => ['user' =>
320
                    ['id', 'name'],
321
                ],
322
                'rows' => ['user' =>
323
                    [
324
                        ['id' => 5, 'name' => 'John'],
325
                        ['id' => 6, 'name' => 'Jane'],
326
                    ],
327
                ],
328
            ],
329
            'ok associative format' => [
330
                'structure' => [
331
                    'user' => [
332
                        ['id' => 5, 'name' => 'John'],
333
                        ['id' => 6, 'name' => 'Jane'],
334
                    ],
335
                ],
336
                'exception' => null,
337
                'tables' => ['user'],
338
                'columns' => ['user' =>
339
                    ['id', 'name'],
340
                ],
341
                'rows' => ['user' =>
342
                    [
343
                        ['id' => 5, 'name' => 'John'],
344
                        ['id' => 6, 'name' => 'Jane'],
345
                    ],
346
                ],
347
            ],
348
            'ok multiple' => [
349
                'structure' => [
350
                    'user' => [
351
                        ['id' => 5, 'name' => 'John'],
352
                        ['id' => 6, 'name' => 'Jane'],
353
                    ],
354
                    'course' => [
355
                        ['id' => 7, 'name' => '101'],
356
                        ['id' => 8, 'name' => '102'],
357
                    ],
358
                ],
359
                'exception' => null,
360
                'tables' => ['user', 'course'],
361
                'columns' => [
362
                    'user' => ['id', 'name'],
363
                    'course' => ['id', 'name'],
364
                ],
365
                'rows' => [
366
                    'user' => [
367
                        ['id' => 5, 'name' => 'John'],
368
                        ['id' => 6, 'name' => 'Jane'],
369
                    ],
370
                    'course' => [
371
                        ['id' => 7, 'name' => '101'],
372
                        ['id' => 8, 'name' => '102'],
373
                    ],
374
                ],
375
            ],
376
        ];
377
    }
378
 
379
    /**
380
     * @dataProvider from_array_provider
381
     * @covers ::from_array
382
     */
383
    public function test_from_array(array $structure, ?string $exception,
11 efrain 384
        array $tables, array $columns, array $rows, ?bool $repeated = false): void {
1 efrain 385
 
386
        $ds = new phpunit_dataset();
387
 
388
        // We need public properties to check the basis.
389
        $dsref = new \ReflectionClass($ds);
390
        $dstables = $dsref->getProperty('tables');
391
        $dscolumns = $dsref->getProperty('columns');
392
        $dsrows = $dsref->getProperty('rows');
393
 
394
        // We are expecting an exception.
395
        if (!empty($exception)) {
396
            $this->expectException('coding_exception');
397
            $this->expectExceptionMessage($exception);
398
        }
399
 
400
        $ds->from_array($structure);
401
        if ($repeated) {
402
            $ds->from_array($structure);
403
        }
404
 
405
        $this->assertIsArray($dstables->getValue($ds));
406
        $this->assertSame($tables, $dstables->getValue($ds));
407
        $this->assertIsArray($dscolumns->getValue($ds));
408
        $this->assertSame($columns, $dscolumns->getValue($ds));
409
        $this->assertIsArray($dsrows->getValue($ds));
410
        $this->assertEquals($rows, $dsrows->getValue($ds)); // Equals because of stringified integers on load.
411
    }
412
 
413
    /**
414
     * test_load_csv() data provider.
415
     */
416
    public function load_csv_provider() {
417
 
418
        return [
419
            'repeated csv table many files' => [
420
                'files' => [
421
                    __DIR__ . '/fixtures/sample_dataset.xml',
422
                    'user' => __DIR__ . '/fixtures/sample_dataset.csv',
423
                ],
424
                'exception' => 'csv_dataset_format, table already added to dataset: user',
425
                'tables' => [],
426
                'columns' => [],
427
                'rows' => [],
428
            ],
429
            'ok one csv file' => [
430
                'files' => [
431
                    'user' => __DIR__ . '/fixtures/sample_dataset.csv',
432
                ],
433
                'exception' => null,
434
                'tables' => ['user'],
435
                'columns' => ['user' =>
436
                    ['id', 'username', 'email']
437
                ],
438
                'rows' => ['user' =>
439
                    [
440
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
441
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
442
                    ]
443
                ],
444
            ],
445
            'ok multiple csv files' => [
446
                'files' => [
447
                    'user1' => __DIR__ . '/fixtures/sample_dataset.csv',
448
                    'user2' => __DIR__ . '/fixtures/sample_dataset.csv',
449
                ],
450
                'exception' => null,
451
                'tables' => ['user1', 'user2'],
452
                'columns' => [
453
                    'user1' => ['id', 'username', 'email'],
454
                    'user2' => ['id', 'username', 'email'],
455
                ],
456
                'rows' => [
457
                    'user1' => [
458
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
459
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
460
                    ],
461
                    'user2' => [
462
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
463
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
464
                    ],
465
                ],
466
            ],
467
        ];
468
    }
469
 
470
    /**
471
     * @dataProvider load_csv_provider
472
     * @covers ::load_csv
473
     */
474
    public function test_load_csv(array $files, ?string $exception,
11 efrain 475
        array $tables, array $columns, array $rows): void {
1 efrain 476
 
477
        $ds = new phpunit_dataset();
478
 
479
        // We need public properties to check the basis.
480
        $dsref = new \ReflectionClass($ds);
481
        $dstables = $dsref->getProperty('tables');
482
        $dscolumns = $dsref->getProperty('columns');
483
        $dsrows = $dsref->getProperty('rows');
484
 
485
        // We are expecting an exception.
486
        if (!empty($exception)) {
487
            $this->expectException('coding_exception');
488
            $this->expectExceptionMessage($exception);
489
        }
490
 
491
        $ds->from_files($files);
492
 
493
        $this->assertIsArray($dstables->getValue($ds));
494
        $this->assertSame($tables, $dstables->getValue($ds));
495
        $this->assertIsArray($dscolumns->getValue($ds));
496
        $this->assertSame($columns, $dscolumns->getValue($ds));
497
        $this->assertIsArray($dsrows->getValue($ds));
498
        $this->assertEquals($rows, $dsrows->getValue($ds)); // Equals because of stringified integers on load.
499
    }
500
 
501
    /**
502
     * test_load_xml() data provider.
503
     */
504
    public function load_xml_provider() {
505
 
506
        return [
507
            'repeated xml table multiple files' => [
508
                'files' => [
509
                    'user' => __DIR__ . '/fixtures/sample_dataset.csv',
510
                    __DIR__ . '/fixtures/sample_dataset.xml',
511
                ],
512
                'exception' => 'xml_dataset_format, table already added to dataset: user',
513
                'tables' => [],
514
                'columns' => [],
515
                'rows' => [],
516
            ],
517
            'repeated xml table one file' => [
518
                'files' => [__DIR__ . '/fixtures/sample_dataset_repeated.xml'],
519
                'exception' => 'xml_dataset_format, table already added to dataset: user',
520
                'tables' => [],
521
                'columns' => [],
522
                'rows' => [],
523
            ],
524
            'wrong dataset element' => [
525
                'files' => [__DIR__ . '/fixtures/sample_dataset_wrong_dataset.xml'],
526
                'exception' => 'xml_dataset_format, main xml element must be "dataset", found: nodataset',
527
                'tables' => [],
528
                'columns' => [],
529
                'rows' => [],
530
            ],
531
            'wrong table element' => [
532
                'files' => [__DIR__ . '/fixtures/sample_dataset_wrong_table.xml'],
533
                'exception' => 'xml_dataset_format, only "table" elements allowed, found: notable',
534
                'tables' => [],
535
                'columns' => [],
536
                'rows' => [],
537
            ],
538
            'wrong table name attribute' => [
539
                'files' => [__DIR__ . '/fixtures/sample_dataset_wrong_attribute.xml'],
540
                'exception' => 'xml_dataset_format, "table" element only allows "name" attribute',
541
                'tables' => [],
542
                'columns' => [],
543
                'rows' => [],
544
            ],
545
            'only col and row allowed' => [
546
                'files' => [__DIR__ . '/fixtures/sample_dataset_only_colrow.xml'],
547
                'exception' => 'xml_dataset_format, only "column or "row" elements allowed, found: nocolumn',
548
                'tables' => [],
549
                'columns' => [],
550
                'rows' => [],
551
            ],
552
            'wrong value element' => [
553
                'files' => [__DIR__ . '/fixtures/sample_dataset_wrong_value.xml'],
554
                'exception' => 'xml_dataset_format, only "value" elements allowed, found: novalue',
555
                'tables' => [],
556
                'columns' => [],
557
                'rows' => [],
558
            ],
559
            'column before row' => [
560
                'files' => [__DIR__ . '/fixtures/sample_dataset_col_before_row.xml'],
561
                'exception' => 'xml_dataset_format, "column" elements always must be before "row" ones',
562
                'tables' => [],
563
                'columns' => [],
564
                'rows' => [],
565
            ],
566
            'row after column' => [
567
                'files' => [__DIR__ . '/fixtures/sample_dataset_row_after_col.xml'],
568
                'exception' => 'xml_dataset_format, "row" elements always must be after "column" ones',
569
                'tables' => [],
570
                'columns' => [],
571
                'rows' => [],
572
            ],
573
            'number of columns' => [
574
                'files' => [__DIR__ . '/fixtures/sample_dataset_number_of_columns.xml'],
575
                'exception' => 'xml_dataset_format, number of columns must match number of values, found: 4 vs 3',
576
                'tables' => [],
577
                'columns' => [],
578
                'rows' => [],
579
            ],
580
            'ok one xml file' => [
581
                'files' => [__DIR__ . '/fixtures/sample_dataset.xml'],
582
                'exception' => null,
583
                'tables' => ['user'],
584
                'columns' => ['user' =>
585
                    ['id', 'username', 'email']
586
                ],
587
                'rows' => ['user' =>
588
                    [
589
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
590
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
591
                    ]
592
                ],
593
            ],
594
            'ok multiple xml files' => [
595
                'files' => [
596
                    'user1' => __DIR__ . '/fixtures/sample_dataset.csv',
597
                    __DIR__ . '/fixtures/sample_dataset.xml',
598
                ],
599
                'exception' => null,
600
                'tables' => ['user1', 'user'],
601
                'columns' => [
602
                    'user1' => ['id', 'username', 'email'],
603
                    'user' => ['id', 'username', 'email'],
604
                ],
605
                'rows' => [
606
                    'user1' => [
607
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
608
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
609
                    ],
610
                    'user' => [
611
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
612
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
613
                    ],
614
                ],
615
            ],
616
            'ok many tables in one xml' => [
617
                'files' => [__DIR__ . '/fixtures/sample_dataset_many.xml'],
618
                'exception' => null,
619
                'tables' => ['user', 'course'],
620
                'columns' => [
621
                    'user' => ['id', 'username', 'email'],
622
                    'course' => ['id', 'shortname', 'fullname'],
623
                ],
624
                'rows' => [
625
                    'user' => [
626
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
627
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
628
                    ],
629
                    'course' => [
630
                        ['id' => 6, 'shortname' => '101', 'fullname' => '1-0-1'],
631
                        ['id' => 8, 'shortname' => '202', 'fullname' => '2-0-2'],
632
                    ],
633
                ],
634
            ],
635
        ];
636
    }
637
 
638
    /**
639
     * @dataProvider load_xml_provider
640
     * @covers ::load_xml
641
     */
642
    public function test_load_xml(array $files, ?string $exception,
11 efrain 643
        array $tables, array $columns, array $rows): void {
1 efrain 644
 
645
        $ds = new phpunit_dataset();
646
 
647
        // We need public properties to check the basis.
648
        $dsref = new \ReflectionClass($ds);
649
        $dstables = $dsref->getProperty('tables');
650
        $dscolumns = $dsref->getProperty('columns');
651
        $dsrows = $dsref->getProperty('rows');
652
 
653
        // We are expecting an exception.
654
        if (!empty($exception)) {
655
            $this->expectException('coding_exception');
656
            $this->expectExceptionMessage($exception);
657
        }
658
 
659
        $ds->from_files($files);
660
 
661
        $this->assertIsArray($dstables->getValue($ds));
662
        $this->assertSame($tables, $dstables->getValue($ds));
663
        $this->assertIsArray($dscolumns->getValue($ds));
664
        $this->assertSame($columns, $dscolumns->getValue($ds));
665
        $this->assertIsArray($dsrows->getValue($ds));
666
        $this->assertEquals($rows, $dsrows->getValue($ds)); // Equals because of stringified integers on load.
667
    }
668
 
669
    /**
670
     * test_to_database() data provider.
671
     */
672
    public function to_database_provider() {
673
 
674
        return [
675
            'wrong table requested' => [
676
                'files' => [__DIR__ . '/fixtures/sample_dataset_insert.xml'],
677
                'filter' => ['wrongtable'],
678
                'exception' => 'dataset_to_database, table is not in the dataset: wrongtable',
679
                'columns' => [],
680
                'rows' => [],
681
            ],
682
            'one table insert' => [
683
                'files' => [__DIR__ . '/fixtures/sample_dataset_insert.xml'],
684
                'filter' => [],
685
                'exception' => null,
686
                'columns' => [
687
                    'user' => ['username', 'email'],
688
                ],
689
                'rows' => ['user' =>
690
                    [
691
                        (object)['username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
692
                        (object)['username' => 'pepa.novak', 'email' => 'pepa@example.com'],
693
                    ]
694
                ],
695
            ],
696
            'one table import' => [
697
                'files' => [__DIR__ . '/fixtures/sample_dataset.xml'],
698
                'filter' => [],
699
                'exception' => null,
700
                'columns' => [
701
                    'user' => ['id', 'username', 'email'],
702
                ],
703
                'rows' => ['user' =>
704
                    [
705
                        (object)['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
706
                        (object)['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
707
                    ]
708
                ],
709
            ],
710
            'multiple table many files import' => [
711
                'files' => [
712
                    __DIR__ . '/fixtures/sample_dataset.xml',
713
                    __DIR__ . '/fixtures/sample_dataset2.xml',
714
                ],
715
                'filter' => [],
716
                'exception' => null,
717
                'columns' => [
718
                    'user' => ['id', 'username', 'email'],
719
                    'course' => ['id', 'shortname', 'fullname'],
720
                ],
721
                'rows' => [
722
                    'user' => [
723
                        (object)['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
724
                        (object)['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
725
                    ],
726
                    'course' => [
727
                        (object)['id' => 6, 'shortname' => '101', 'fullname' => '1-0-1'],
728
                        (object)['id' => 8, 'shortname' => '202', 'fullname' => '2-0-2'],
729
                    ],
730
                ],
731
            ],
732
            'multiple table one file import' => [
733
                'files' => [__DIR__ . '/fixtures/sample_dataset_many.xml'],
734
                'filter' => [],
735
                'exception' => null,
736
                'columns' => [
737
                    'user' => ['id', 'username', 'email'],
738
                    'course' => ['id', 'shortname', 'fullname'],
739
                ],
740
                'rows' => [
741
                    'user' => [
742
                        (object)['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
743
                        (object)['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
744
                    ],
745
                    'course' => [
746
                        (object)['id' => 6, 'shortname' => '101', 'fullname' => '1-0-1'],
747
                        (object)['id' => 8, 'shortname' => '202', 'fullname' => '2-0-2'],
748
                    ],
749
                ],
750
            ],
751
            'filtering tables' => [
752
                'files' => [__DIR__ . '/fixtures/sample_dataset_many.xml'],
753
                'filter' => ['course'],
754
                'exception' => null,
755
                'columns' => [
756
                    'user' => ['id', 'username', 'email'],
757
                    'course' => ['id', 'shortname', 'fullname'],
758
                ],
759
                'rows' => [
760
                    'user' => [], // Table user is being excluded via filter, expect no rows sent to database.
761
                    'course' => [
762
                        (object)['id' => 6, 'shortname' => '101', 'fullname' => '1-0-1'],
763
                        (object)['id' => 8, 'shortname' => '202', 'fullname' => '2-0-2'],
764
                    ],
765
                ],
766
            ],
767
        ];
768
    }
769
 
770
    /**
771
     * @dataProvider to_database_provider
772
     * @covers ::to_database
773
     */
11 efrain 774
    public function test_to_database(array $files, ?array $filter, ?string $exception, array $columns, array $rows): void {
1 efrain 775
        global $DB;
776
 
777
        $this->resetAfterTest();
778
 
779
        // Grab the status before loading to database.
780
        $before = [];
781
        foreach ($columns as $tablename => $tablecolumns) {
782
            if (!isset($before[$tablename])) {
783
                $before[$tablename] = [];
784
            }
785
            $before[$tablename] = $DB->get_records($tablename, null, '', implode(', ', $tablecolumns));
786
        }
787
 
788
        $ds = new phpunit_dataset();
789
 
790
        // We are expecting an exception.
791
        if (!empty($exception)) {
792
            $this->expectException('coding_exception');
793
            $this->expectExceptionMessage($exception);
794
        }
795
 
796
        $ds->from_files($files);
797
        $ds->to_database($filter);
798
 
799
        // Grab the status after loading to database.
800
        $after = [];
801
        foreach ($columns as $tablename => $tablecolumns) {
802
            if (!isset($after[$tablename])) {
803
                $after[$tablename] = [];
804
            }
805
            $sortandcol = implode(', ', $tablecolumns);
806
            $after[$tablename] = $DB->get_records($tablename, null, $sortandcol, $sortandcol);
807
        }
808
 
809
        // Differences must match the expectations.
810
        foreach ($rows as $tablename => $expectedrows) {
811
            $changes = array_udiff($after[$tablename], $before[$tablename], function ($b, $a) {
812
                if ((array)$b > (array)$a) {
813
                    return 1;
814
                } else if ((array)$b < (array)$a) {
815
                    return -1;
816
                } else {
817
                    return 0;
818
                }
819
            });
820
            $this->assertEquals(array_values($expectedrows), array_values($changes));
821
        }
822
    }
823
 
824
    /**
825
     * test_get_rows() data provider.
826
     */
827
    public function get_rows_provider() {
828
 
829
        return [
830
            'wrong table requested' => [
831
                'files' => [__DIR__ . '/fixtures/sample_dataset_many.xml'],
832
                'filter' => ['wrongtable'],
833
                'exception' => 'dataset_get_rows, table is not in the dataset: wrongtable',
834
                'rows' => [],
835
            ],
836
            'ok get rows from empty tables' => [
837
                'files' => [__DIR__ . '/fixtures/sample_dataset_many_with_empty.xml'],
838
                'filter' => ['empty1', 'empty2'],
839
                'exception' => null,
840
                'rows' => [
841
                    'empty1' => [],
842
                    'empty2' => [],
843
                ],
844
            ],
845
            'ok get rows from one table' => [
846
                'files' => [__DIR__ . '/fixtures/sample_dataset_many_with_empty.xml'],
847
                'filter' => ['user'],
848
                'exception' => null,
849
                'rows' => [
850
                    'user' => [
851
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
852
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
853
                    ],
854
                ],
855
            ],
856
            'ok get rows from two tables' => [
857
                'files' => [__DIR__ . '/fixtures/sample_dataset_many_with_empty.xml'],
858
                'filter' => ['user', 'course'],
859
                'exception' => null,
860
                'rows' => [
861
                    'user' => [
862
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
863
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
864
                    ],
865
                    'course' => [
866
                        ['id' => 6, 'shortname' => '101', 'fullname' => '1-0-1'],
867
                        ['id' => 8, 'shortname' => '202', 'fullname' => '2-0-2'],
868
                    ],
869
                ],
870
            ],
871
            'ok get rows from three tables' => [
872
                'files' => [__DIR__ . '/fixtures/sample_dataset_many_with_empty.xml'],
873
                'filter' => ['user', 'empty1', 'course'],
874
                'exception' => null,
875
                'rows' => [
876
                    'user' => [
877
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
878
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
879
                    ],
880
                    'empty1' => [],
881
                    'course' => [
882
                        ['id' => 6, 'shortname' => '101', 'fullname' => '1-0-1'],
883
                        ['id' => 8, 'shortname' => '202', 'fullname' => '2-0-2'],
884
                    ],
885
                ],
886
            ],
887
            'ok no filter returns all' => [
888
                'files' => [__DIR__ . '/fixtures/sample_dataset_many_with_empty.xml'],
889
                'filter' => [],
890
                'exception' => null,
891
                'rows' => [
892
                    'user' => [
893
                        ['id' => 5, 'username' => 'bozka.novakova', 'email' => 'bozka@example.com'],
894
                        ['id' => 7, 'username' => 'pepa.novak', 'email' => 'pepa@example.com'],
895
                    ],
896
                    'empty1' => [],
897
                    'empty2' => [],
898
                    'course' => [
899
                        ['id' => 6, 'shortname' => '101', 'fullname' => '1-0-1'],
900
                        ['id' => 8, 'shortname' => '202', 'fullname' => '2-0-2'],
901
                    ],
902
                ],
903
            ],
904
        ];
905
    }
906
 
907
    /**
908
     * @dataProvider get_rows_provider
909
     * @covers ::get_rows
910
     */
11 efrain 911
    public function test_get_rows(array $files, array $filter, ?string $exception, array $rows): void {
1 efrain 912
 
913
        $ds = new phpunit_dataset();
914
 
915
        // We are expecting an exception.
916
        if (!empty($exception)) {
917
            $this->expectException('coding_exception');
918
            $this->expectExceptionMessage($exception);
919
        }
920
 
921
        $ds->from_files($files);
922
        $this->assertEquals($rows, $ds->get_rows($filter));
923
    }
924
}