Passed
Push — master ( 22923d...e0306a )
by Maurício
01:57
created

ShapeFileTest::shapes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 118
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 29
nc 1
nop 0
dl 0
loc 118
rs 9.456
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * phpMyAdmin ShapeFile library
7
 * <https://github.com/phpmyadmin/shapefile/>.
8
 *
9
 * Copyright 2006-2007 Ovidio <ovidio AT users.sourceforge.net>
10
 * Copyright 2016 - 2017 Michal Čihař <[email protected]>
11
 *
12
 * This program is free software; you can redistribute it and/or
13
 * modify it under the terms of the GNU General Public License
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, you can download one from
23
 * https://www.gnu.org/copyleft/gpl.html.
24
 */
25
26
namespace PhpMyAdminTest\ShapeFile;
27
28
use PhpMyAdmin\ShapeFile\ShapeFile;
29
use PhpMyAdmin\ShapeFile\ShapeRecord;
30
use PHPUnit\Framework\TestCase;
31
32
use function count;
33
use function method_exists;
34
35
class ShapeFileTest extends TestCase
36
{
37
    /**
38
     * Tests loading of a file.
39
     *
40
     * @param string   $filename Name of file
41
     * @param int      $records  Expected number of records
42
     * @param int|null $parts    Expected number of parts in first record
43
     *
44
     * @dataProvider provideFiles
45
     */
46
    public function testLoad(string $filename, int $records, ?int $parts): void
47
    {
48
        $shp = new ShapeFile(1);
49
        $shp->loadFromFile($filename);
50
        $this->assertEquals('', $shp->lastError);
51
        $this->assertEquals($records, count($shp->records));
52
        if ($parts === null) {
53
            return;
54
        }
55
56
        $this->assertEquals($parts, count($shp->records[0]->shpData['parts']));
57
    }
58
59
    /**
60
     * Data provider for file loading tests.
61
     *
62
     * @return array
63
     */
64
    public static function provideFiles(): array
65
    {
66
        return [
67
            [
68
                'data/capitals.*',
69
                652,
70
                null,
71
            ],
72
            [
73
                'data/mexico.*',
74
                32,
75
                3,
76
            ],
77
            [
78
                'data/Czech_Republic_AL2.*',
79
                1,
80
                1,
81
            ],
82
            [
83
                'data/w001n05f.*',
84
                16,
85
                1,
86
            ],
87
            [
88
                'data/bc_hospitals.*',
89
                44,
90
                null,
91
            ],
92
            [
93
                'data/multipoint.*',
94
                312,
95
                null,
96
            ],
97
        ];
98
    }
99
100
    /**
101
     * Test error handling in loader.
102
     *
103
     * @param string $filename name to load
104
     *
105
     * @dataProvider provideErrorFiles
106
     */
107
    public function testLoadError(string $filename): void
108
    {
109
        $shp = new ShapeFile(1);
110
        $shp->loadFromFile($filename);
111
        $this->assertNotEquals('', $shp->lastError);
112
    }
113
114
    /**
115
     * Test load an empty file name
116
     */
117
    public function testLoadEmptyFilename(): void
118
    {
119
        $shp = new ShapeFile(1);
120
        $shp->loadFromFile('');
121
        if (ShapeFile::supportsDbase()) {
122
            $this->assertEquals('It wasn\'t possible to find the DBase file ""', $shp->lastError);
123
124
            return;
125
        }
126
127
        $this->assertEquals('Not a SHP file (file code mismatch)', $shp->lastError);
128
    }
129
130
    /**
131
     * Test to call getDBFHeader on a non loaded file
132
     */
133
    public function testGetDBFHeader(): void
134
    {
135
        $shp = new ShapeFile(1);
136
        $this->assertNull($shp->getDBFHeader());
137
    }
138
139
    /**
140
     * Data provider for file loading error tests.
141
     *
142
     * @return array
143
     */
144
    public static function provideErrorFiles(): array
145
    {
146
        $result = [
147
            ['data/no-shp.*'],
148
            ['data/missing.*'],
149
            ['data/invalid-shp.*'],
150
        ];
151
152
        if (ShapeFile::supportsDbase()) {
153
            $result[] = ['data/no-dbf.*'];
154
            $result[] = ['data/invalid-dbf.*'];
155
        }
156
157
        return $result;
158
    }
159
160
    /**
161
     * Creates test data.
162
     */
163
    private function createTestData(): void
164
    {
165
        $shp = new ShapeFile(1);
166
167
        $record0 = new ShapeRecord(1);
168
        $record0->addPoint(['x' => 482131.764567, 'y' => 2143634.39608]);
169
170
        $record1 = new ShapeRecord(11);
171
        $record1->addPoint(['x' => 472131.764567, 'y' => 2143634.39608, 'z' => 220, 'm' => 120]);
172
173
        $record2 = new ShapeRecord(21);
174
        $record2->addPoint(['x' => 492131.764567, 'y' => 2143634.39608, 'z' => 150, 'm' => 80]);
175
176
        $record3 = new ShapeRecord(3);
177
        $record3->addPoint(['x' => 482131.764567, 'y' => 2143634.39608], 0);
178
        $record3->addPoint(['x' => 482132.764567, 'y' => 2143635.39608], 0);
179
        $record3->addPoint(['x' => 482131.764567, 'y' => 2143635.39608], 1);
180
        $record3->addPoint(['x' => 482132.764567, 'y' => 2143636.39608], 1);
181
182
        $shp->addRecord($record0);
183
        $shp->addRecord($record1);
184
        $shp->addRecord($record2);
185
        $shp->addRecord($record3);
186
187
        $shp->setDBFHeader(
188
            [
189
                [
190
                    'ID',
191
                    'N',
192
                    8,
193
                    0,
194
                ],
195
                [
196
                    'DESC',
197
                    'C',
198
                    50,
199
                    0,
200
                ],
201
            ]
202
        );
203
204
        $shp->records[0]->dbfData['ID'] = '1';
205
        $shp->records[0]->dbfData['DESC'] = 'AAAAAAAAA';
206
207
        $shp->records[1]->dbfData['ID'] = '2';
208
        $shp->records[1]->dbfData['DESC'] = 'BBBBBBBBBB';
209
210
        $shp->records[2]->dbfData['ID'] = '3';
211
        $shp->records[2]->dbfData['DESC'] = 'CCCCCCCCCCC';
212
213
        $shp->records[3]->dbfData['ID'] = '4';
214
        $shp->records[3]->dbfData['DESC'] = 'CCCCCCCCCCC';
215
216
        $shp->saveToFile('./data/test_shape.*');
217
    }
218
219
    /**
220
     * Tests creating file.
221
     */
222
    public function testCreate(): void
223
    {
224
        if (! ShapeFile::supportsDbase()) {
225
            $this->markTestSkipped('dbase extension missing');
226
        }
227
228
        $this->createTestData();
229
230
        $shp = new ShapeFile(1);
231
        $shp->loadFromFile('./data/test_shape.*');
232
        $this->assertEquals(4, count($shp->records));
233
    }
234
235
    /**
236
     * Tests removing record from a file.
237
     */
238
    public function testDelete(): void
239
    {
240
        if (! ShapeFile::supportsDbase()) {
241
            $this->markTestSkipped('dbase extension missing');
242
        }
243
244
        $this->createTestData();
245
246
        $shp = new ShapeFile(1);
247
        $shp->loadFromFile('./data/test_shape.*');
248
        $shp->deleteRecord(1);
249
        $shp->saveToFile();
250
        $this->assertEquals(3, count($shp->records));
251
252
        $shp = new ShapeFile(1);
253
        $shp->loadFromFile('./data/test_shape.*');
254
        $this->assertEquals(3, count($shp->records));
255
    }
256
257
    /**
258
     * Test adding record to a file.
259
     */
260
    public function testAdd(): void
261
    {
262
        if (! ShapeFile::supportsDbase()) {
263
            $this->markTestSkipped('dbase extension missing');
264
        }
265
266
        $this->createTestData();
267
268
        $shp = new ShapeFile(1);
269
        $shp->loadFromFile('./data/test_shape.*');
270
271
        $record0 = new ShapeRecord(1);
272
        $record0->addPoint(['x' => 482131.764567, 'y' => 2143634.39608]);
273
274
        $shp->addRecord($record0);
275
        $shp->records[4]->dbfData['ID'] = '4';
276
        $shp->records[4]->dbfData['DESC'] = 'CCCCCCCCCCC';
277
278
        $shp->saveToFile();
279
        $this->assertEquals(5, count($shp->records));
280
281
        $shp = new ShapeFile(1);
282
        $shp->loadFromFile('./data/test_shape.*');
283
        $this->assertEquals(5, count($shp->records));
284
    }
285
286
    /**
287
     * Tests saving without DBF.
288
     */
289
    public function testSaveNoDBF(): void
290
    {
291
        $shp = new ShapeFile(1);
292
        $shp->saveToFile('./data/test_nodbf.*');
293
294
        if (method_exists($this, 'assertFileDoesNotExist')) {
295
            $this->assertFileDoesNotExist('./data/test_nodbf.dbf');
296
        } else {
297
            $this->assertFileNotExists('./data/test_nodbf.dbf');
298
        }
299
    }
300
301
    /**
302
     * Test shape naming.
303
     */
304
    public function testShapeName(): void
305
    {
306
        $obj = new ShapeRecord(1);
307
        $this->assertEquals('Point', $obj->getShapeName());
308
        $obj = new ShapeFile(1);
309
        $this->assertEquals('Point', $obj->getShapeName());
310
        $obj = new ShapeRecord(-1);
311
        $this->assertEquals('Shape -1', $obj->getShapeName());
312
    }
313
314
    /**
315
     * Test shapes save/load round robin.
316
     *
317
     * @param int   $type   Shape type
318
     * @param array $points Points
319
     *
320
     * @dataProvider shapes
321
     */
322
    public function testShapeSaveLoad(int $type, array $points): void
323
    {
324
        $filename = './data/test_shape-' . $type . '.*';
325
        $shp = new ShapeFile($type);
326
        $shp->setDBFHeader([
327
            [
328
                'ID',
329
                'N',
330
                19,
331
                0,
332
            ],
333
            [
334
                'DESC',
335
                'C',
336
                14,
337
                0,
338
            ],
339
        ]);
340
341
        $record0 = new ShapeRecord($type);
342
343
        foreach ($points as $point) {
344
            $record0->addPoint($point[0], $point[1]);
345
        }
346
347
        $shp->addRecord($record0);
348
349
        $shp->saveToFile($filename);
350
351
        $shp2 = new ShapeFile($type);
352
        $shp2->loadFromFile($filename);
353
354
        $this->assertEquals(
355
            count($shp->records),
356
            count($shp2->records)
357
        );
358
359
        $record = $shp->records[0];
360
        $record2 = $shp2->records[0];
361
362
        $items = [
363
            'numparts',
364
            'numpoints',
365
        ];
366
        foreach ($items as $item) {
367
            if (! isset($record->shpData[$item])) {
368
                continue;
369
            }
370
371
            $this->assertEquals($record->shpData[$item], $record2->shpData[$item]);
372
        }
373
374
        /* Test deletion works */
375
        $record->deletePoint();
376
    }
377
378
    /**
379
     * Test shapes save/load round robin with z coordinate.
380
     *
381
     * @param int   $type   Shape type
382
     * @param array $points Points
383
     *
384
     * @dataProvider shapes
385
     */
386
    public function testZetShapeSaveLoad(int $type, array $points): void
387
    {
388
        $this->testShapeSaveLoad($type + 10, $points);
389
    }
390
391
    /**
392
     * Test shapes save/load round robin with measure.
393
     *
394
     * @param int   $type   Shape type
395
     * @param array $points Points
396
     *
397
     * @dataProvider shapes
398
     */
399
    public function testMeasureShapeSaveLoad(int $type, array $points): void
400
    {
401
        $this->testShapeSaveLoad($type + 20, $points);
402
    }
403
404
    /**
405
     * Data provider for save/load testing.
406
     *
407
     * @return array
408
     */
409
    public static function shapes(): array
410
    {
411
        return [
412
            [
413
                1,
414
                [
415
                    [
416
                        [
417
                            'x' => 10,
418
                            'y' => 20,
419
                        ],
420
                        0,
421
                    ],
422
                ],
423
            ],
424
            [
425
                3,
426
                [
427
                    [
428
                        [
429
                            'x' => 10,
430
                            'y' => 20,
431
                        ],
432
                        0,
433
                    ],
434
                    [
435
                        [
436
                            'x' => 20,
437
                            'y' => 20,
438
                        ],
439
                        0,
440
                    ],
441
                    [
442
                        [
443
                            'x' => 20,
444
                            'y' => 20,
445
                        ],
446
                        1,
447
                    ],
448
                    [
449
                        [
450
                            'x' => 20,
451
                            'y' => 10,
452
                        ],
453
                        1,
454
                    ],
455
                ],
456
            ],
457
            [
458
                5,
459
                [
460
                    [
461
                        [
462
                            'x' => 10,
463
                            'y' => 20,
464
                        ],
465
                        0,
466
                    ],
467
                    [
468
                        [
469
                            'x' => 20,
470
                            'y' => 20,
471
                        ],
472
                        0,
473
                    ],
474
                    [
475
                        [
476
                            'x' => 20,
477
                            'y' => 20,
478
                        ],
479
                        1,
480
                    ],
481
                    [
482
                        [
483
                            'x' => 20,
484
                            'y' => 10,
485
                        ],
486
                        1,
487
                    ],
488
                    [
489
                        [
490
                            'x' => 20,
491
                            'y' => 10,
492
                        ],
493
                        2,
494
                    ],
495
                    [
496
                        [
497
                            'x' => 10,
498
                            'y' => 20,
499
                        ],
500
                        2,
501
                    ],
502
                ],
503
            ],
504
            [
505
                8,
506
                [
507
                    [
508
                        [
509
                            'x' => 10,
510
                            'y' => 20,
511
                        ],
512
                        0,
513
                    ],
514
                    [
515
                        [
516
                            'x' => 20,
517
                            'y' => 20,
518
                        ],
519
                        0,
520
                    ],
521
                    [
522
                        [
523
                            'x' => 20,
524
                            'y' => 10,
525
                        ],
526
                        0,
527
                    ],
528
                ],
529
            ],
530
        ];
531
    }
532
533
    public function testSearch(): void
534
    {
535
        $shp = new ShapeFile(0);
536
        $shp->loadFromFile('data/capitals.*');
537
        /* Nonexisting entry or no dbase support */
538
        $this->assertEquals(
539
            -1,
540
            $shp->getIndexFromDBFData('CNTRY_NAME', 'nonexisting')
541
        );
542
        if (! ShapeFile::supportsDbase()) {
543
            return;
544
        }
545
546
        $this->assertEquals(
547
            218,
548
            $shp->getIndexFromDBFData('CNTRY_NAME', 'Czech Republic')
549
        );
550
    }
551
}
552