]> git.openstreetmap.org Git - nominatim.git/commitdiff
move looksLikeLatLonPair into lib.php, basic PHP test suite using phpunit
authorMarc Tobias Metten <mtmail@gmx.net>
Tue, 23 Sep 2014 20:53:20 +0000 (22:53 +0200)
committerMarc Tobias Metten <mtmail@gmx.net>
Tue, 23 Sep 2014 20:53:20 +0000 (22:53 +0200)
.gitignore
lib/Geocode.php
lib/lib.php
phpunit.xml [new file with mode: 0644]
tests-php/Nominatim/NominatimTest.php [new file with mode: 0644]
tests-php/README.txt [new file with mode: 0644]
tests-php/bootstrap.php [new file with mode: 0644]
tests/README.md

index 0c54ce7670719bc7c7816c652d242b30a5654d7b..54af2ad328a3a163d6106e65fd7df86ba659dde1 100644 (file)
@@ -1,4 +1,5 @@
 *.log
+*.pyc
 
 nominatim/*.d
 nominatim/*.o
@@ -27,3 +28,4 @@ compile
 data/wiki_import.sql
 data/wiki_specialphrases.sql
 data/osmosischange.osc
+
index c8cc4c4a6621b02838fa19caee61075383d434f7..2955b94ff57a663a15a0542ba0586cbec85fe3ce 100644 (file)
                        }
 
                        // Do we have anything that looks like a lat/lon pair?
-                       if (preg_match('/\\b([NS])[ ]+([0-9]+[0-9.]*)[ ]+([0-9.]+)?[, ]+([EW])[ ]+([0-9]+)[ ]+([0-9]+[0-9.]*)?\\b/', $sQuery, $aData))
-                       {
-                               $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60);
-                               $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60);
-                               if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1)
-                               {
-                                       $this->setNearPoint(array($fQueryLat, $fQueryLon));
-                                       $sQuery = trim(str_replace($aData[0], ' ', $sQuery));
-                               }
-                       }
-                       elseif (preg_match('/\\b([0-9]+)[ ]+([0-9]+[0-9.]*)?[ ]+([NS])[, ]+([0-9]+)[ ]+([0-9]+[0-9.]*)?[ ]+([EW])\\b/', $sQuery, $aData))
-                       {
-                               $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60);
-                               $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60);
-                               if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1)
-                               {
-                                       $this->setNearPoint(array($fQueryLat, $fQueryLon));
-                                       $sQuery = trim(str_replace($aData[0], ' ', $sQuery));
-                               }
-                       }
-                       elseif (preg_match('/(\\[|^|\\b)(-?[0-9]+[0-9]*\\.[0-9]+)[, ]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]|$|\\b)/', $sQuery, $aData))
-                       {
-                               $fQueryLat = $aData[2];
-                               $fQueryLon = $aData[3];
-                               if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1)
-                               {
-                                       $this->setNearPoint(array($fQueryLat, $fQueryLon));
-                                       $sQuery = trim(str_replace($aData[0], ' ', $sQuery));
-                               }
+                       if ( $aLooksLike = looksLikeLatLonPair($sQuery) ){
+                               $this->setNearPoint(array($aLooksLike['lat'], $aLooksLike['lon']));
+                               $sQuery = $aLooksLike['query'];                 
                        }
 
                        $aSearchResults = array();
index 74e971b4804f1d32dc6da9bde7a05dfc4abfe2f0..e200202bd6d869136e8fcda26eee8bbc6cb3a650 100644 (file)
        {
                return "'".$s."'";
        }
+
+       // returns boolean
+       function validLatLon($fLat,$fLon)
+       {
+               return ($fLat <= 90.1 && $fLat >= -90.1 && $fLon <= 180.1 && $fLon >= -180.1);
+       }
+
+       // Do we have anything that looks like a lat/lon pair?
+       // returns array(lat,lon,query_with_lat_lon_removed)
+       // or null
+       function looksLikeLatLonPair($sQuery)
+       {
+               $sFound    = null;
+               $fQueryLat = null;
+               $fQueryLon = null;
+
+               // degrees decimal minutes
+               // N 40 26.767, W 79 58.933
+               // N 40°26.767′, W 79°58.933′
+               //                  1         2                   3                  4         5            6
+               if (preg_match('/\\b([NS])[ ]+([0-9]+[0-9.]*)[° ]+([0-9.]+)?[′\']*[, ]+([EW])[ ]+([0-9]+)[° ]+([0-9]+[0-9.]*)[′\']*?\\b/', $sQuery, $aData))
+               {
+                       $sFound    = $aData[0];
+                       $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60);
+                       $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60);
+               }
+               // degrees decimal minutes
+               // 40 26.767 N, 79 58.933 W
+               // 40° 26.767′ N 79° 58.933′ W
+               //                      1             2                      3          4            5                    6
+               elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\']*[ ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\' ]+([EW])\\b/', $sQuery, $aData))
+               {
+                       $sFound    = $aData[0];
+                       $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60);
+                       $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60);
+               }
+               // degrees decimal seconds
+               // N 40 26 46 W 79 58 56
+               // N 40° 26′ 46″ W, 79° 58′ 56″
+               //                      1        2            3            4                5        6            7            8
+               elseif (preg_match('/\\b([NS])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*[, ]+([EW])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*\\b/', $sQuery, $aData))
+               {
+                       $sFound    = $aData[0];
+                       $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60 + $aData[4]/3600);
+                       $fQueryLon = ($aData[5]=='E'?1:-1) * ($aData[6] + $aData[7]/60 + $aData[8]/3600);
+               }
+               // degrees decimal seconds
+               // 40 26 46 N 79 58 56 W
+               // 40° 26′ 46″ N, 79° 58′ 56″ W
+               //                      1            2            3            4          5            6            7            8
+               elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([EW])\\b/', $sQuery, $aData))
+               {
+                       $sFound    = $aData[0];
+                       $fQueryLat = ($aData[4]=='N'?1:-1) * ($aData[1] + $aData[2]/60 + $aData[3]/3600);
+                       $fQueryLon = ($aData[8]=='E'?1:-1) * ($aData[5] + $aData[6]/60 + $aData[7]/3600);
+               }
+               // degrees decimal
+               // N 40.446° W 79.982°
+               //                      1        2                               3        4
+               elseif (preg_match('/\\b([NS])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*[, ]+([EW])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*\\b/', $sQuery, $aData))
+               {
+                       $sFound    = $aData[0];
+                       $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2]);
+                       $fQueryLon = ($aData[3]=='E'?1:-1) * ($aData[4]);
+               }
+               // degrees decimal
+               // 40.446° N 79.982° W
+               //                      1                           2          3                           4
+               elseif (preg_match('/\\b([0-9]+[0-9]*\\.[0-9]+)[° ]+([NS])[, ]+([0-9]+[0-9]*\\.[0-9]+)[° ]+([EW])\\b/', $sQuery, $aData))
+               {
+                       $sFound    = $aData[0];
+                       $fQueryLat = ($aData[2]=='N'?1:-1) * ($aData[1]);
+                       $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[3]);
+               }
+               // degrees decimal
+               // 12.34, 56.78
+               // [12.456,-78.90]
+               //                   1          2                             3                        4
+               elseif (preg_match('/(\\[|^|\\b)(-?[0-9]+[0-9]*\\.[0-9]+)[, ]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]|$|\\b)/', $sQuery, $aData))
+               {
+                       $sFound    = $aData[0];
+                       $fQueryLat = $aData[2];
+                       $fQueryLon = $aData[3];
+               }
+
+               if (!validLatLon($fQueryLat, $fQueryLon)) return;
+               $sQuery = trim(str_replace($sFound, ' ', $sQuery));
+
+               return array('lat' => $fQueryLat, 'lon' => $fQueryLon, 'query' => $sQuery);
+       }
\ No newline at end of file
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644 (file)
index 0000000..bea876d
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false"
+    backupStaticAttributes="false"
+    colors="true"
+    convertErrorsToExceptions="true"
+    convertNoticesToExceptions="true"
+    convertWarningsToExceptions="true"
+    processIsolation="false"
+    stopOnFailure="false"
+    syntaxCheck="true"
+    bootstrap="tests-php/bootstrap.php"
+    >
+    <php>
+    </php>
+    <testsuites>
+        <testsuite name="Nominatim PHP Test Suite">
+            <directory>./tests-php/Nominatim</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+        <whitelist>
+            <directory>./lib/</directory>
+        </whitelist>
+    </filter>
+
+</phpunit>
diff --git a/tests-php/Nominatim/NominatimTest.php b/tests-php/Nominatim/NominatimTest.php
new file mode 100644 (file)
index 0000000..68519e4
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+
+namespace Nominatim;
+require 'lib/lib.php';
+
+
+class NominatimTest extends \PHPUnit_Framework_TestCase
+{
+
+       protected function setUp()
+       {
+       }
+
+
+       public function test_addQuotes()
+       {
+               // FIXME: not quoting existing quote signs is probably a bug
+               $this->assertSame("'St. John's'", addQuotes("St. John's"));
+               $this->assertSame("''", addQuotes(''));
+       }
+
+       public function test_looksLikeLatLonPair()
+       {
+               // no coordinates expected
+               $this->assertNull(looksLikeLatLonPair(''));
+               $this->assertNull(looksLikeLatLonPair('abc'));
+               $this->assertNull(looksLikeLatLonPair('12 34'));
+               $this->assertNull(looksLikeLatLonPair('200.1 89.9')); // because latitude > 180
+
+               // coordinates expected
+               $this->assertNotNull(looksLikeLatLonPair('0.0 -0.0'));
+
+               $this->assertEquals(
+                               array( 'lat' => 12.456, 'lon' => -78.90, 'query' => 'abc   def'),
+                               looksLikeLatLonPair(' abc 12.456 -78.90 def ')
+                       );
+
+               $this->assertEquals(
+                               array( 'lat' => 12.456, 'lon' => -78.90, 'query' => ''),
+                               looksLikeLatLonPair(' [12.456,-78.90] ')
+                       );
+
+               // http://en.wikipedia.org/wiki/Geographic_coordinate_conversion
+               // these all represent the same location
+               $aQueries = array(
+                                       '40 26.767 N 79 58.933 W',
+                                       '40° 26.767′ N 79° 58.933′ W',
+                                       "40° 26.767' N 79° 58.933' W",
+                                       'N 40 26.767, W 79 58.933',
+                                       'N 40°26.767′, W 79°58.933′',
+                                       "N 40°26.767', W 79°58.933'",
+
+                                       '40 26 46 N 79 58 56 W',
+                                       '40° 26′ 46″ N 79° 58′ 56″ W',
+                                       'N 40 26 46 W 79 58 56',
+                                       'N 40° 26′ 46″, W 79° 58′ 56″',
+                                       'N 40° 26\' 46", W 79° 58\' 56"',
+
+                                       '40.446 -79.982',
+                                       '40.446,-79.982',
+                                       '40.446° N 79.982° W',
+                                       'N 40.446° W 79.982°',
+
+                                       '[40.446 -79.982]',
+                                       '       40.446  ,   -79.982     ',
+               );
+
+
+               foreach($aQueries as $sQuery){
+                       $aRes = looksLikeLatLonPair($sQuery);
+                       $this->assertEquals( 40.446, $aRes['lat'], 'degrees decimal ' . $sQuery, 0.01);
+                       $this->assertEquals(-79.982, $aRes['lon'], 'degrees decimal ' . $sQuery, 0.01);
+               }
+
+       }
+
+}
diff --git a/tests-php/README.txt b/tests-php/README.txt
new file mode 100644 (file)
index 0000000..31fd21e
--- /dev/null
@@ -0,0 +1,13 @@
+Basic unit tests of PHP code. Very low coverage. Doesn't cover interaction
+with the webserver/HTTP or database (yet).
+
+You need to have
+https://phpunit.de/manual/4.2/en/
+installed.
+
+To execute the test suite run
+$ phpunit
+
+It will read phpunit.xml which points to the library, test path, bootstrap
+strip and set other parameters.
+
diff --git a/tests-php/bootstrap.php b/tests-php/bootstrap.php
new file mode 100644 (file)
index 0000000..a4abe2d
--- /dev/null
@@ -0,0 +1,2 @@
+<?php
+
index 9b053e157560b4988cd3c369383533e4cd799555..0e4c269bf40083c540bfc894a251f065dfe99ba3 100644 (file)
@@ -21,7 +21,7 @@ Usage
 
  * get prerequisites
 
-     [sudo] pip install lettuce nose pytidylib haversine
+     [sudo] pip install lettuce nose pytidylib haversine psycopg2
 
  * run the tests