Completed
Branch testing (7f3043)
by Hennik
05:13
created

MysqlTest::tearDown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
use LaravelSpatial\SpatialServiceProvider;
4
use GeoJson\Geometry\GeometryCollection;
5
use GeoJson\Geometry\LineString;
6
use GeoJson\Geometry\MultiPoint;
7
use GeoJson\Geometry\MultiPolygon;
8
use GeoJson\Geometry\Point;
9
use GeoJson\Geometry\Polygon;
10
use Illuminate\Filesystem\Filesystem;
1 ignored issue
show
Bug introduced by
This use statement conflicts with another class in this namespace, Filesystem. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
11
use Illuminate\Support\Facades\DB;
12
use Laravel\BrowserKitTesting\TestCase as BaseTestCase;
1 ignored issue
show
Bug introduced by
This use statement conflicts with another class in this namespace, BaseTestCase. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
13
14
class MysqlTest extends BaseTestCase
15
{
16
    protected $is_postgres = false;
17
18
    protected $after_fix = false;
19
20
    /**
21
     * Boots the application.
22
     *
23
     * @return \Illuminate\Foundation\Application
24
     */
25
    public function createApplication()
26
    {
27
        $app = require __DIR__.'/../../vendor/laravel/laravel/bootstrap/app.php';
28
        $app->register(SpatialServiceProvider::class);
29
30
        $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();
31
32
        $app['config']->set('database.default', 'mysql');
33
        $app['config']->set('database.connections.mysql.host', env('DB_HOST', '127.0.0.1'));
34
        $app['config']->set('database.connections.mysql.database', 'spatial_test');
35
        $app['config']->set('database.connections.mysql.username', 'root');
36
        $app['config']->set('database.connections.mysql.password', '');
37
        $app['config']->set('database.connections.mysql.modes', [
38
            'ONLY_FULL_GROUP_BY',
39
            'STRICT_TRANS_TABLES',
40
            'NO_ZERO_IN_DATE',
41
            'NO_ZERO_DATE',
42
            'ERROR_FOR_DIVISION_BY_ZERO',
43
            'NO_ENGINE_SUBSTITUTION',
44
        ]);
45
46
        return $app;
47
    }
48
49
    /**
50
     * Setup DB before each test.
51
     *
52
     * @return void
53
     */
54
    public function setUp()
55
    {
56
        parent::setUp();
57
58
        $this->after_fix = $this->isMySQL8AfterFix();
59
60
        $this->onMigrations(function ($migrationClass) {
61
            (new $migrationClass())->up();
62
        });
63
64
        //\DB::listen(function($sql) {
65
        //    var_dump($sql);
66
        //});
67
    }
68
69
    public function tearDown()
70
    {
71
        $this->onMigrations(function ($migrationClass) {
72
            (new $migrationClass())->down();
73
        }, true);
74
75
        parent::tearDown();
76
    }
77
78
    // MySQL 8.0.4 fixed bug #26941370 and bug #88031
79
    protected function isMySQL8AfterFix()
80
    {
81
        $results = DB::select(DB::raw('select version()'));
82
        $mysql_version = $results[0]->{'version()'};
83
84
        return version_compare($mysql_version, '8.0.4', '>=');
85
    }
86
87
    protected function assertDatabaseHas($table, array $data, $connection = null)
88
    {
89
        if (method_exists($this, 'seeInDatabase')) {
90
            $this->seeInDatabase($table, $data, $connection);
91
        } else {
92
            parent::assertDatabaseHas($table, $data, $connection);
93
        }
94
    }
95
96
    protected function assertException($exceptionName)
97
    {
98
        if (method_exists(parent::class, 'expectException')) {
99
            parent::expectException($exceptionName);
100
        } else {
101
            $this->setExpectedException($exceptionName);
1 ignored issue
show
Deprecated Code introduced by
The function PHPUnit_Framework_TestCase::setExpectedException() has been deprecated: Method deprecated since Release 5.2.0; use expectException() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

101
            /** @scrutinizer ignore-deprecated */ $this->setExpectedException($exceptionName);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
102
        }
103
    }
104
105
    private function onMigrations(\Closure $closure, $reverse_sort = false)
106
    {
107
        $fileSystem = new Filesystem();
108
        $classFinder = new Tools\ClassFinder();
109
110
        $migrations = $fileSystem->files(__DIR__.'/Migrations');
111
        $reverse_sort ? rsort($migrations, SORT_STRING) : sort($migrations, SORT_STRING);
112
113
        foreach ($migrations as $file) {
114
            $fileSystem->requireOnce($file);
115
            $migrationClass = $classFinder->findClass($file);
116
117
            $closure($migrationClass);
118
        }
119
    }
120
121
    public function testSpatialFieldsNotDefinedException()
122
    {
123
        $this->assertException(\LaravelSpatial\Exceptions\SpatialFieldsNotDefinedException::class);
124
125
        $geo = new NoSpatialFieldsModel();
126
        $geo->geometry = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property geometry does not exist on NoSpatialFieldsModel. Did you mean geometries?
Loading history...
127
        $geo->save();
128
129
        NoSpatialFieldsModel::all();
130
    }
131
132
    public function testInsertPoint()
133
    {
134
        $geo = new GeometryModel();
135
        $geo->location = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
136
        $geo->save();
137
        $this->assertDatabaseHas($geo->getTable(), ['id' => $geo->id]);
138
    }
139
140
    public function testInsertLineString()
141
    {
142
        $geo = new GeometryModel();
143
144
        $geo->location = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
145
        $geo->line = new LineString([new Point([1, 1]), new Point([2, 2])]);
1 ignored issue
show
Bug introduced by
The property line does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
146
        $geo->save();
147
        $this->assertDatabaseHas($geo->getTable(), ['id' => $geo->id]);
148
    }
149
150
    public function testInsertPolygon()
151
    {
152
        $geo = new GeometryModel();
153
154
        $geo->location = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
155
        $geo->shape = new Polygon([[[0, 10],[10, 10],[10, 0],[0, 0],[0, 10]]]);
1 ignored issue
show
Bug introduced by
The property shape does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
156
        $geo->save();
157
        $this->assertDatabaseHas($geo->getTable(), ['id' => $geo->id]);
158
    }
159
160
    public function testInsertMultiPoint()
161
    {
162
        $geo = new GeometryModel();
163
164
        $geo->location = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
165
        $geo->multi_locations = new MultiPoint([new Point([1, 1]), new Point([2, 2])]);
1 ignored issue
show
Bug introduced by
The property multi_locations does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
166
        $geo->save();
167
        $this->assertDatabaseHas($geo->getTable(), ['id' => $geo->id]);
168
    }
169
170
    public function testInsertMultiPolygon()
171
    {
172
        $geo = new GeometryModel();
173
174
        $geo->location = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
175
176
        $geo->multi_shapes = new MultiPolygon([
1 ignored issue
show
Bug introduced by
The property multi_shapes does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
177
            new Polygon([[[0, 10],[10, 10],[10, 0],[0, 0],[0, 10]]]),
178
            new Polygon([[[0, 0],[0, 5],[5, 5],[5, 0],[0, 0]]]),
179
        ]);
180
        $geo->save();
181
        $this->assertDatabaseHas($geo->getTable(), ['id' => $geo->id]);
182
    }
183
184
    public function testInsertGeometryCollection()
185
    {
186
        $geo = new GeometryModel();
187
188
        $geo->location = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
189
190
        $geo->multi_geometries = new GeometryCollection([
1 ignored issue
show
Bug introduced by
The property multi_geometries does not exist on GeometryModel. Did you mean geometries?
Loading history...
191
            new Polygon([[[0, 10],[10, 10],[10, 0],[0, 0],[0, 10]]]),
192
            new Polygon([[[0, 0],[0, 5],[5, 5],[5, 0],[0, 0]]]),
193
            new Point([0, 0]),
194
        ]);
195
        $geo->save();
196
        $this->assertDatabaseHas($geo->getTable(), ['id' => $geo->id]);
197
    }
198
199
    public function testUpdate()
200
    {
201
        $geo = new GeometryModel();
202
        $geo->location = new Point([1, 2]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
203
        $geo->save();
204
205
        $to_update = GeometryModel::all()->first();
206
        $to_update->location = new Point([2, 3]);
207
        $to_update->save();
208
209
        $this->assertDatabaseHas($geo->getTable(), ['id' => $to_update->id]);
210
211
        $all = GeometryModel::all();
212
        $this->assertCount(1, $all);
213
214
        $updated = $all->first();
215
        $this->assertInstanceOf(Point::class, $updated->location);
216
        $this->assertEquals(2, $updated->location->getCoordinates()[0]);
217
        $this->assertEquals(3, $updated->location->getCoordinates()[1]);
218
    }
219
220
    public function testDistance()
221
    {
222
        $loc1 = new GeometryModel();
223
        $loc1->location = new Point([1, 1]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
224
        $loc1->save();
225
226
        $loc2 = new GeometryModel();
227
        $loc2->location = new Point([2, 2]); // Distance from loc1: 1.4142135623731
228
        $loc2->save();
229
230
        $loc3 = new GeometryModel();
231
        $loc3->location = new Point([3, 3]); // Distance from loc1: 2.8284271247462
232
        $loc3->save();
233
234
        $a = GeometryModel::distance('location', $loc1->location, 2)->get();
235
        $this->assertCount(2, $a);
236
        $this->assertTrue($a->contains('location', $loc1->location));
2 ignored issues
show
Bug introduced by
The method contains() does not exist on Countable. It seems like you code against a sub-type of Countable such as Illuminate\Pagination\LengthAwarePaginator or Illuminate\Support\Collection or Illuminate\Http\Resources\Json\ResourceCollection or SplObjectStorage or Carbon\CarbonPeriod or Illuminate\Pagination\Paginator or Symfony\Component\Finder\Finder or Illuminate\Support\ViewErrorBag or Symfony\Component\HttpFoundation\HeaderBag or PHPUnit_Extensions_TestDecorator or PHPUnit_Framework_TestCase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

236
        $this->assertTrue($a->/** @scrutinizer ignore-call */ contains('location', $loc1->location));
Loading history...
Bug introduced by
The method contains() does not exist on Traversable. It seems like you code against a sub-type of Traversable such as Illuminate\Pagination\LengthAwarePaginator or Illuminate\Support\Collection or Illuminate\Http\Resources\Json\ResourceCollection or Illuminate\Pagination\Paginator or Symfony\Component\Finder\Finder or Symfony\Component\HttpFoundation\HeaderBag or SplObjectStorage or Carbon\CarbonPeriod. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

236
        $this->assertTrue($a->/** @scrutinizer ignore-call */ contains('location', $loc1->location));
Loading history...
237
        $this->assertTrue($a->contains('location', $loc2->location));
238
        $this->assertFalse($a->contains('location', $loc3->location));
239
240
        // Excluding self
241
        $b = GeometryModel::distanceExcludingSelf('location', $loc1->location, 2)->get();
242
        $this->assertCount(1, $b);
243
        $this->assertFalse($b->contains('location', $loc1->location));
244
        $this->assertTrue($b->contains('location', $loc2->location));
245
        $this->assertFalse($b->contains('location', $loc3->location));
246
247
        $c = GeometryModel::distance('location', $loc1->location, 1)->get();
248
        $this->assertCount(1, $c);
249
        $this->assertTrue($c->contains('location', $loc1->location));
250
        $this->assertFalse($c->contains('location', $loc2->location));
251
        $this->assertFalse($c->contains('location', $loc3->location));
252
    }
253
254
    public function testDistanceSphere()
255
    {
256
        try {
257
            $loc1 = new GeometryModel();
258
            $loc1->location = new Point([-73.971732, 40.767864]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
259
            $loc1->save();
260
261
            $loc2 = new GeometryModel();
262
            $loc2->location = new Point([-73.971271, 40.767664]); // Distance from loc1: 44.741406484588
263
            $loc2->save();
264
265
            $loc3 = new GeometryModel();
266
            $loc3->location = new Point([-73.977619, 40.761434]); // Distance from loc1: 870.06424066202
267
            $loc3->save();
268
269
            $a = GeometryModel::distanceSphere('location', $loc1->location, 200)->get();
270
            $this->assertCount(2, $a);
271
            $this->assertTrue($a->contains('location', $loc1->location));
272
            $this->assertTrue($a->contains('location', $loc2->location));
273
            $this->assertFalse($a->contains('location', $loc3->location));
274
275
            // Excluding self
276
            $b = GeometryModel::distanceSphereExcludingSelf('location', $loc1->location, 200)->get();
277
            $this->assertCount(1, $b);
278
            $this->assertFalse($b->contains('location', $loc1->location));
279
            $this->assertTrue($b->contains('location', $loc2->location));
280
            $this->assertFalse($b->contains('location', $loc3->location));
281
282
            if ($this->is_postgres || $this->after_fix) {
283
                $c = GeometryModel::distanceSphere('location', $loc1->location, 44.741406484236)->get();
284
            } else {
285
                $c = GeometryModel::distanceSphere('location', $loc1->location, 44.741406484587)->get();
286
            }
287
            $this->assertCount(1, $c);
288
            $this->assertTrue($c->contains('location', $loc1->location));
289
            $this->assertFalse($c->contains('location', $loc2->location));
290
            $this->assertFalse($c->contains('location', $loc3->location));
291
        } catch (\Illuminate\Database\QueryException $e) {
292
            if (strpos($e->getMessage(), 'FUNCTION spatial_test.ST_Distance_Sphere does not exist') > -1) {
293
                $this->markTestSkipped('Spherical distance tests [distanceSphere*()] not supported on the current DBMS');
294
            }
295
            throw $e;
296
        }
297
    }
298
299
    public function testDistanceValue()
300
    {
301
        $loc1 = new GeometryModel();
302
        $loc1->location = new Point([1, 1]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
303
        $loc1->save();
304
305
        $loc2 = new GeometryModel();
306
        $loc2->location = new Point([2, 2]); // Distance from loc1: 1.4142135623731
307
        $loc2->save();
308
309
        $a = GeometryModel::distanceValue('location', $loc1->location)->get();
310
        $this->assertCount(2, $a);
311
        $this->assertEquals(0, $a[0]->distance);
312
        $this->assertEquals(1.4142135623, $a[1]->distance); // PHP floats' 11th+ digits don't matter
313
    }
314
315
    public function testDistanceSphereValue()
316
    {
317
        try {
318
            $loc1 = new GeometryModel();
319
            $loc1->location = new Point([-73.971732, 40.767864]);
1 ignored issue
show
Bug introduced by
The property location does not seem to exist on GeometryModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
320
            $loc1->save();
321
322
            $loc2 = new GeometryModel();
323
            $loc2->location = new Point([-73.971271, 40.767664]); // Distance from loc1: 44.741406484236
324
            $loc2->save();
325
326
            $a = GeometryModel::distanceSphereValue('location', $loc1->location)->get();
327
            $this->assertCount(2, $a);
328
            $this->assertEquals(0, $a[0]->distance);
329
330
            if ($this->is_postgres) {
331
                $this->assertEquals("44.7415664", number_format($a[1]->distance, 7)); // Postgres calculates this differently?
332
            } elseif ($this->after_fix) {
333
                $this->assertEquals(44.7414064842, $a[1]->distance); // PHP floats' 11th+ digits don't matter
334
            } else {
335
                $this->assertEquals(44.7414064845, $a[1]->distance); // PHP floats' 11th+ digits don't matter
336
            }
337
        } catch (\Illuminate\Database\QueryException $e) {
338
            if (strpos($e->getMessage(), 'FUNCTION spatial_test.ST_Distance_Sphere does not exist') > -1) {
339
                $this->markTestSkipped('Spherical distance tests [distanceSphere*()] not supported on the current DBMS');
340
            }
341
            throw $e;
342
        }
343
    }
344
345
    //public function testBounding() {
346
    //    $point = new Point([0, 0]);
347
    //
348
    //    $linestring1 = \GeoJson\Geometry\LineString::fromWkt("LINESTRING(1 1, 2 2)");
349
    //    $linestring2 = \GeoJson\Geometry\LineString::fromWkt("LINESTRING(20 20, 24 24)");
350
    //    $linestring3 = \GeoJson\Geometry\LineString::fromWkt("LINESTRING(0 10, 10 10)");
351
    //
352
    //    $geo1 = new GeometryModel();
353
    //    $geo1->location = $point;
354
    //    $geo1->line = $linestring1;
355
    //    $geo1->save();
356
    //
357
    //    $geo2 = new GeometryModel();
358
    //    $geo2->location = $point;
359
    //    $geo2->line = $linestring2;
360
    //    $geo2->save();
361
    //
362
    //    $geo3 = new GeometryModel();
363
    //    $geo3->location = $point;
364
    //    $geo3->line = $linestring3;
365
    //    $geo3->save();
366
    //
367
    //    $polygon = new Polygon([[[0, 10],[10, 10],[10, 0],[0, 0],[0, 10]]]);
368
    //
369
    //    $result = GeometryModel::Bounding($polygon, 'line')->get();
370
    //    $this->assertCount(2, $result);
371
    //    $this->assertTrue($result->contains($geo1));
372
    //    $this->assertFalse($result->contains($geo2));
373
    //    $this->assertTrue($result->contains($geo3));
374
    //
375
    //}
376
}
377