Henning Snater has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/69630


Change subject: Enhanced input string splitting in GeoCoordinate parsers
......................................................................

Enhanced input string splitting in GeoCoordinate parsers

If a coordinate input string cannot be split using the predefined separator, it
is split by using the direction symbols, DMS symbols or space character if the
input string is formatted properly.

Change-Id: Id89dcf80e84a9d1867046bc251185fd0d47e067c
---
M ValueParsers/includes/parsers/DdCoordinateParser.php
M ValueParsers/includes/parsers/DmCoordinateParser.php
M ValueParsers/includes/parsers/DmsCoordinateParser.php
M ValueParsers/includes/parsers/FloatCoordinateParser.php
M ValueParsers/tests/phpunit/parsers/DdCoordinateParserTest.php
M ValueParsers/tests/phpunit/parsers/DmCoordinateParserTest.php
M ValueParsers/tests/phpunit/parsers/DmsCoordinateParserTest.php
M ValueParsers/tests/phpunit/parsers/FloatCoordinateParserTest.php
M ValueParsers/tests/phpunit/parsers/GeoCoordinateParserTest.php
9 files changed, 297 insertions(+), 53 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DataValues 
refs/changes/30/69630/1

diff --git a/ValueParsers/includes/parsers/DdCoordinateParser.php 
b/ValueParsers/includes/parsers/DdCoordinateParser.php
index 882124c..80b6eaf 100644
--- a/ValueParsers/includes/parsers/DdCoordinateParser.php
+++ b/ValueParsers/includes/parsers/DdCoordinateParser.php
@@ -91,7 +91,7 @@
                        throw new ParseException( 'Not a geographical 
coordinate in DD format' );
                }
 
-               $coordinates = explode( $this->getOption( 
self::OPT_SEPARATOR_SYMBOL ), $value );
+               $coordinates = $this->splitString( $value );
 
                if ( count( $coordinates ) !== 2 ) {
                        throw new LogicException( 'A coordinates string with an 
incorrect segment count has made it through validation' );
@@ -236,6 +236,44 @@
        }
 
        /**
+        * Splits a string into two strings using the separator specified in 
the options. If the string
+        * could not be split using the separator, the method will try to split 
the string by analyzing
+        * the used symbols. If the string could not be split into two parts, 
an empty array is
+        * returned.
+        *
+        * @param string $normalizedCoordinateString
+        * @return string[]
+        */
+       protected function splitString( $normalizedCoordinateString ) {
+               $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+
+               $normalizedCoordinateSegments = explode( $separator, 
$normalizedCoordinateString );
+
+               if( count( $normalizedCoordinateSegments ) !== 2 ) {
+                       // Separator not present within the string, trying to 
figure out the segments by
+                       // splitting after the first direction character or 
degree symbol:
+                       $delimiters = array(
+                               $this->getOption( self::OPT_NORTH_SYMBOL ),
+                               $this->getOption( self::OPT_SOUTH_SYMBOL ),
+                               '°'
+                       );
+
+                       foreach( $delimiters as $delimiter ) {
+                               $delimiterPos = mb_strpos( 
$normalizedCoordinateString, $delimiter );
+                               if( $delimiterPos !== false ) {
+                                       $normalizedCoordinateSegments = array(
+                                               mb_substr( 
$normalizedCoordinateString, 0, $delimiterPos + 1 ),
+                                               mb_substr( 
$normalizedCoordinateString, $delimiterPos + 1 )
+                                       );
+                                       break;
+                               }
+                       }
+               }
+
+               return $normalizedCoordinateSegments;
+       }
+
+       /**
         * Returns whether the coordinate is in Decimal Degree representation.
         *
         * @since 0.1
@@ -245,19 +283,53 @@
         * @return boolean
         */
        protected function areDDCoordinates( $rawCoordinateString ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+               $rawCoordinate = $this->splitString( $rawCoordinateString );
 
-               $baseRegExp = '\d{1,3}(|\.\d{1,20})°';
+               if( count( $rawCoordinate ) !== 2 ) {
+                       return false;
+               }
 
-               $nonDirectionalRegExp = '/^(-)?' . $baseRegExp . $sep . '(-)?' 
. $baseRegExp . '$/i';
-               $directionalRegExp = '/^' . $baseRegExp . '('
-                       . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|'
-                       . $this->getOption( self::OPT_SOUTH_SYMBOL ) .')' . 
$sep . $baseRegExp . '('
-                       . $this->getOption( self::OPT_EAST_SYMBOL ) .'|'
-                       . $this->getOption( self::OPT_WEST_SYMBOL ) . ')?$/i';
+               $baseRegExp = '\d{1,3}(\.\d{1,20})?°';
 
-               return preg_match( $nonDirectionalRegExp, $rawCoordinateString )
-                       || preg_match( $directionalRegExp, $rawCoordinateString 
);
+               // Cache whether the coordinates are specified in directional 
format (a mixture of
+               // directional and non-directional is regarded invalid).
+               $directional = false;
+
+               $match = false;
+
+               foreach( $rawCoordinate as $i => $segment ) {
+                       $direction = '('
+                               . $this->getOption( self::OPT_NORTH_SYMBOL ) . 
'|'
+                               . $this->getOption( self::OPT_SOUTH_SYMBOL ) . 
')';
+
+                       if( $i === 1 ) {
+                               $direction = '('
+                                       . $this->getOption( 
self::OPT_EAST_SYMBOL ) . '|'
+                                       . $this->getOption( 
self::OPT_WEST_SYMBOL ) . ')';
+                       }
+
+                       $match = preg_match( '/^' . $baseRegExp . $direction . 
'$/i', $segment );
+
+                       if( $directional ) {
+                               // Directionality is only set after parsing 
latitude: When the latitude is
+                               // is directional, the longitude needs to be as 
well. Therefore we break here since
+                               // checking for directionality is the only 
check needed for longitude.
+                               break;
+                       } elseif( $match ) {
+                               // Latitude is directional, no need to check 
for non-directionality.
+                               $directional = true;
+                               continue;
+                       }
+
+                       $match = preg_match( '/^(-)?' . $baseRegExp . '$/i', 
$segment );
+
+                       if( !$match ) {
+                               // Does neither match directional nor 
non-directional.
+                               break;
+                       }
+               }
+
+               return $match;
        }
 
 }
diff --git a/ValueParsers/includes/parsers/DmCoordinateParser.php 
b/ValueParsers/includes/parsers/DmCoordinateParser.php
index 4c23dd0..96feb39 100644
--- a/ValueParsers/includes/parsers/DmCoordinateParser.php
+++ b/ValueParsers/includes/parsers/DmCoordinateParser.php
@@ -93,7 +93,7 @@
                        throw new ParseException( 'Not a geographical 
coordinate in DM format' );
                }
 
-               $coordinates = explode( $this->getOption( 
self::OPT_SEPARATOR_SYMBOL ), $value );
+               $coordinates = $this->splitString( $value );
 
                if ( count( $coordinates ) !== 2 ) {
                        throw new LogicException( 'A coordinates string with an 
incorrect segment count has made it through validation' );
@@ -268,6 +268,45 @@
        }
 
        /**
+        * Splits a string into two strings using the separator specified in 
the options. If the string
+        * could not be split using the separator, the method will try to split 
the string by analyzing
+        * the used symbols. If the string could not be split into two parts, 
an empty array is
+        * returned.
+        *
+        * @param string $normalizedCoordinateString
+        * @return string[]
+        */
+       protected function splitString( $normalizedCoordinateString ) {
+               $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+
+               $normalizedCoordinateSegments = explode( $separator, 
$normalizedCoordinateString );
+
+               if( count( $normalizedCoordinateSegments ) !== 2 ) {
+                       // Separator not present within the string, trying to 
figure out the segments by
+                       // splitting after the first direction character or 
minute symbol:
+                       $delimiters = array(
+                               $this->getOption( self::OPT_NORTH_SYMBOL ),
+                               $this->getOption( self::OPT_SOUTH_SYMBOL ),
+                               '′',
+                               '\''
+                       );
+
+                       foreach( $delimiters as $delimiter ) {
+                               $delimiterPos = mb_strpos( 
$normalizedCoordinateString, $delimiter );
+                               if( $delimiterPos !== false ) {
+                                       $normalizedCoordinateSegments = array(
+                                               mb_substr( 
$normalizedCoordinateString, 0, $delimiterPos + 1 ),
+                                               mb_substr( 
$normalizedCoordinateString, $delimiterPos + 1 )
+                                       );
+                                       break;
+                               }
+                       }
+               }
+
+               return $normalizedCoordinateSegments;
+       }
+
+       /**
         * Returns whether the coordinate is in Decimal Minute representation.
         *
         * @since 0.1
@@ -277,9 +316,7 @@
         * @return boolean
         */
        protected function areDMCoordinates( $rawCoordinateString ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
-
-               $rawCoordinate = explode( $sep, trim( $rawCoordinateString ) );
+               $rawCoordinate = $this->splitString( $rawCoordinateString );
 
                if( count( $rawCoordinate ) !== 2 ) {
                        return false;
@@ -297,20 +334,14 @@
                $directional = false;
 
                foreach( $rawCoordinate as $i => $segment ) {
-                       $segment = trim( $segment );
-
                        $direction = '('
-                               . $this->getOption( self::OPT_NORTH_SYMBOL )
-                               . '|'
-                               . $this->getOption( self::OPT_SOUTH_SYMBOL )
-                               . ')';
+                               . $this->getOption( self::OPT_NORTH_SYMBOL ) . 
'|'
+                               . $this->getOption( self::OPT_SOUTH_SYMBOL ) . 
')';
 
                        if( $i === 1 ) {
                                $direction = '('
-                                       . $this->getOption( 
self::OPT_EAST_SYMBOL )
-                                       . '|'
-                                       . $this->getOption( 
self::OPT_WEST_SYMBOL )
-                                       . ')';
+                                       . $this->getOption( 
self::OPT_EAST_SYMBOL ) . '|'
+                                       . $this->getOption( 
self::OPT_WEST_SYMBOL ) . ')';
                        }
 
                        $match = preg_match( '/^' . $regExpStrict . $direction 
. '$/i', $segment );
diff --git a/ValueParsers/includes/parsers/DmsCoordinateParser.php 
b/ValueParsers/includes/parsers/DmsCoordinateParser.php
index 5facb57..9ad9f04 100644
--- a/ValueParsers/includes/parsers/DmsCoordinateParser.php
+++ b/ValueParsers/includes/parsers/DmsCoordinateParser.php
@@ -95,7 +95,7 @@
                        throw new ParseException( 'Not a geographical 
coordinate in DMS format' );
                }
 
-               $coordinates = explode( $this->getOption( 
self::OPT_SEPARATOR_SYMBOL ), $value );
+               $coordinates = $this->splitString( $value );
 
                if ( count( $coordinates ) !== 2 ) {
                        throw new LogicException( 'A coordinates string with an 
incorrect segment count has made it through validation' );
@@ -286,6 +286,45 @@
        }
 
        /**
+        * Splits a string into two strings using the separator specified in 
the options. If the string
+        * could not be split using the separator, the method will try to split 
the string by analyzing
+        * the used symbols. If the string could not be split into two parts, 
an empty array is
+        * returned.
+        *
+        * @param string $normalizedCoordinateString
+        * @return string[]
+        */
+       protected function splitString( $normalizedCoordinateString ) {
+               $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+
+               $normalizedCoordinateSegments = explode( $separator, 
$normalizedCoordinateString );
+
+               if( count( $normalizedCoordinateSegments ) !== 2 ) {
+                       // Separator not present within the string, trying to 
figure out the segments by
+                       // splitting after the first direction character or 
second symbol:
+                       $delimiters = array(
+                               $this->getOption( self::OPT_NORTH_SYMBOL ),
+                               $this->getOption( self::OPT_SOUTH_SYMBOL ),
+                               '″',
+                               '"'
+                       );
+
+                       foreach( $delimiters as $delimiter ) {
+                               $delimiterPos = mb_strpos( 
$normalizedCoordinateString, $delimiter );
+                               if( $delimiterPos !== false ) {
+                                       $normalizedCoordinateSegments = array(
+                                               mb_substr( 
$normalizedCoordinateString, 0, $delimiterPos + 1 ),
+                                               mb_substr( 
$normalizedCoordinateString, $delimiterPos + 1 )
+                                       );
+                                       break;
+                               }
+                       }
+               }
+
+               return $normalizedCoordinateSegments;
+       }
+
+       /**
         * Returns whether the coordinate is in DMS representation.
         * TODO: nicify
         *
@@ -296,9 +335,7 @@
         * @return boolean
         */
        protected function areDMSCoordinates( $rawCoordinateString ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
-
-               $rawCoordinates = explode( $sep, trim( $rawCoordinateString ) );
+               $rawCoordinates = $this->splitString( $rawCoordinateString );
 
                if( count( $rawCoordinates ) !== 2 ) {
                        return false;
@@ -317,20 +354,14 @@
                $directional = false;
 
                foreach( $rawCoordinates as $i => $rawCoordinate ) {
-                       $rawCoordinate = trim( $rawCoordinate );
-
                        $direction = '('
-                               . $this->getOption( self::OPT_NORTH_SYMBOL )
-                               . '|'
-                               . $this->getOption( self::OPT_SOUTH_SYMBOL )
-                               . ')';
+                               . $this->getOption( self::OPT_NORTH_SYMBOL ) . 
'|'
+                               . $this->getOption( self::OPT_SOUTH_SYMBOL ) . 
')';
 
                        if( $i === 1 ) {
                                $direction = '('
-                                       . $this->getOption( 
self::OPT_EAST_SYMBOL )
-                                       . '|'
-                                       . $this->getOption( 
self::OPT_WEST_SYMBOL )
-                                       . ')';
+                                       . $this->getOption( 
self::OPT_EAST_SYMBOL ) . '|'
+                                       . $this->getOption( 
self::OPT_WEST_SYMBOL ) . ')';
                        }
 
                        $match = preg_match( '/^' . $regExpStrict . $direction 
. '$/i', $rawCoordinate );
diff --git a/ValueParsers/includes/parsers/FloatCoordinateParser.php 
b/ValueParsers/includes/parsers/FloatCoordinateParser.php
index d4c08ba..8364080 100644
--- a/ValueParsers/includes/parsers/FloatCoordinateParser.php
+++ b/ValueParsers/includes/parsers/FloatCoordinateParser.php
@@ -81,7 +81,7 @@
                        throw new ParseException( 'Not a geographical 
coordinate in float format' );
                }
 
-               $coordinates = explode( $this->getOption( 
self::OPT_SEPARATOR_SYMBOL ), $value );
+               $coordinates = $this->splitString( $value );
 
                if ( count( $coordinates ) !== 2 ) {
                        throw new LogicException( 'A coordinates string with an 
incorrect segment count has made it through validation' );
@@ -116,7 +116,7 @@
         * @return float
         */
        protected function getParsedCoordinate( $coordinate ) {
-               return (float)$this->resolveDirection( $coordinate );
+               return (float)$this->resolveDirection( str_replace( ' ', '', 
$coordinate ) );
        }
 
        /**
@@ -173,7 +173,9 @@
        }
 
        /**
-        * Returns a string with whitespace, control characters and characters 
with ASCII values above 126 removed.
+        * Returns a string trimmed and with control characters and characters 
with ASCII values above
+        * 126 removed. SPACE characters within the string are not removed to 
retain the option to split
+        * the string using that character.
         *
         * @since 0.1
         *
@@ -187,12 +189,53 @@
                foreach ( str_split( $string ) as $character ) {
                        $asciiValue = ord( $character );
 
-                       if ( ( $asciiValue > 32 && $asciiValue < 127 ) || 
$asciiValue == 194 || $asciiValue == 176 ) {
+                       if ( ( $asciiValue >= 32 && $asciiValue < 127 ) || 
$asciiValue == 194 || $asciiValue == 176 ) {
                                $filtered[] = $character;
                        }
                }
 
-               return implode( '', $filtered );
+               return trim( implode( '', $filtered ) );
+       }
+
+       /**
+        * Splits a string into two strings using the separator specified in 
the options. If the string
+        * could not be split using the separator, the method will try to split 
the string by analyzing
+        * the used symbols. If the string could not be split into two parts, 
an empty array is
+        * returned.
+        *
+        * @param string $normalizedCoordinateString
+        * @return string[]
+        */
+       protected function splitString( $normalizedCoordinateString ) {
+               $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+
+               $normalizedCoordinateSegments = explode( $separator, 
$normalizedCoordinateString );
+
+               if( count( $normalizedCoordinateSegments ) !== 2 ) {
+                       // Separator not present within the string, trying to 
figure out the segments by
+                       // splitting at the the first SPACE after the first 
direction character or digit:
+                       $numberRegEx = '-?\d{1,3}(\.\d{1,20})?';
+
+                       $latitudeRegEx = $numberRegEx . '(\s*('
+                               . $this->getOption( self::OPT_NORTH_SYMBOL ) . 
'|'
+                               . $this->getOption( self::OPT_SOUTH_SYMBOL ) 
.'))?';
+
+                       $longitudeRegEx = $numberRegEx . '(\s*('
+                               . $this->getOption( self::OPT_EAST_SYMBOL ) . 
'|'
+                               . $this->getOption( self::OPT_WEST_SYMBOL ) 
.'))?';
+
+                       $match = preg_match(
+                               '/^(' . $latitudeRegEx . ') (' . 
$longitudeRegEx . ')$/',
+                               $normalizedCoordinateString,
+                               $matches
+                       );
+
+                       if( $match ) {
+                               $normalizedCoordinateSegments = array( 
$matches[1], $matches[5] );
+                       }
+               }
+
+               return $normalizedCoordinateSegments;
        }
 
        /**
@@ -206,19 +249,51 @@
         * @return boolean
         */
        protected function areFloatCoordinates( $rawCoordinateString ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+               $rawCoordinate = $this->splitString( $rawCoordinateString );
+
+               if( count( $rawCoordinate ) !== 2 ) {
+                       return false;
+               }
 
                $baseRegExp = '\d{1,3}(\.\d{1,20})?';
 
-               $nonDirectionalRegExp = '/^(-)?' . $baseRegExp . $sep . '(-)?' 
. $baseRegExp . '$/i';
-               $directionalRegExp = '/^' . $baseRegExp . '('
-                       . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|'
-                       . $this->getOption( self::OPT_SOUTH_SYMBOL ) .')' . 
$sep . $baseRegExp . '('
-                       . $this->getOption( self::OPT_EAST_SYMBOL ) .'|'
-                       . $this->getOption( self::OPT_WEST_SYMBOL ) . ')?$/i';
+               // Cache whether the coordinates are specified in directional 
format (a mixture of
+               // directional and non-directional is regarded invalid).
+               $directional = false;
 
-               return preg_match( $nonDirectionalRegExp, $rawCoordinateString )
-               || preg_match( $directionalRegExp, $rawCoordinateString );
+               $match = false;
+
+               foreach( $rawCoordinate as $i => $segment ) {
+                       $segment = str_replace( ' ', '', $segment );
+
+                       $direction = '('
+                               . $this->getOption( self::OPT_NORTH_SYMBOL ) . 
'|'
+                               . $this->getOption( self::OPT_SOUTH_SYMBOL ) . 
')';
+
+                       if( $i === 1 ) {
+                               $direction = '('
+                                       . $this->getOption( 
self::OPT_EAST_SYMBOL ) . '|'
+                                       . $this->getOption( 
self::OPT_WEST_SYMBOL ) . ')';
+                       }
+
+                       $match = preg_match( '/^' . $baseRegExp . $direction . 
'$/i', $segment );
+
+                       if( $directional && !$match ) {
+                               // Latitude is directional, longitude not.
+                               break;
+                       } elseif( $match ) {
+                               continue;
+                       }
+
+                       $match = preg_match( '/^(-)?' . $baseRegExp . '$/i', 
$segment );
+
+                       if( !$match ) {
+                               // Does neither match directional nor 
non-directional.
+                               break;
+                       }
+               }
+
+               return $match;
        }
 
 }
diff --git a/ValueParsers/tests/phpunit/parsers/DdCoordinateParserTest.php 
b/ValueParsers/tests/phpunit/parsers/DdCoordinateParserTest.php
index 2734e00..466619b 100644
--- a/ValueParsers/tests/phpunit/parsers/DdCoordinateParserTest.php
+++ b/ValueParsers/tests/phpunit/parsers/DdCoordinateParserTest.php
@@ -56,6 +56,12 @@
                        '-55°, -37.6176330 °' => array( -55, -37.6176330, 
0.000001 ),
                        '5.5°S,37°W ' => array( -5.5, -37, 0.1 ),
                        '-5.5°,-37° ' => array( -5.5, -37, 0.1 ),
+                       '55.7557860° N 37.6176330° W' => array( 55.7557860, 
-37.6176330, 0.000001 ),
+                       '55.7557860° -37.6176330°' => array( 55.7557860, 
-37.6176330, 0.000001 ),
+                       '55° S 37.6176330 ° W' => array( -55, -37.6176330, 
0.000001 ),
+                       '-55° -37.6176330 °' => array( -55, -37.6176330, 
0.000001 ),
+                       '5.5°S 37°W ' => array( -5.5, -37, 0.1 ),
+                       '-5.5° -37° ' => array( -5.5, -37, 0.1 ),
                );
 
                foreach ( $valid as $value => $expected ) {
diff --git a/ValueParsers/tests/phpunit/parsers/DmCoordinateParserTest.php 
b/ValueParsers/tests/phpunit/parsers/DmCoordinateParserTest.php
index 3aa62d3..518440f 100644
--- a/ValueParsers/tests/phpunit/parsers/DmCoordinateParserTest.php
+++ b/ValueParsers/tests/phpunit/parsers/DmCoordinateParserTest.php
@@ -56,6 +56,12 @@
                        "-55° 30', -37° 30'" => array( -55.5, -37.5, 1 / 60 ),
                        "0° 0.3' S, 0° 0.3' W" => array( -0.005, -0.005, 1 / 
3600 ),
                        "55° 30′, 37° 30′" => array( 55.5, 37.5, 1 / 60 ),
+                       "55° 0' 37° 0'" => array( 55, 37, 1 / 60 ),
+                       "55 ° 30 ' 37 ° 30 '" => array( 55.5, 37.5, 1 / 60 ),
+                       "0° 0' 0° 0'" => array( 0, 0, 1 / 60 ),
+                       "-55° 30 ' -37 ° 30'" => array( -55.5, -37.5, 1 / 60 ),
+                       "0° 0.3' S 0° 0.3' W" => array( -0.005, -0.005, 1 / 
3600 ),
+                       "55° 30′ 37° 30′" => array( 55.5, 37.5, 1 / 60 ),
                );
 
                foreach ( $valid as $value => $expected ) {
diff --git a/ValueParsers/tests/phpunit/parsers/DmsCoordinateParserTest.php 
b/ValueParsers/tests/phpunit/parsers/DmsCoordinateParserTest.php
index fc84fcc..7338d33 100644
--- a/ValueParsers/tests/phpunit/parsers/DmsCoordinateParserTest.php
+++ b/ValueParsers/tests/phpunit/parsers/DmsCoordinateParserTest.php
@@ -61,6 +61,10 @@
                        '0° 0\' 18" N, 0° 0\' 18" E' => array( 0.005, 0.005, 1 
/ 3600 ),
                        ' 0° 0\' 18" S  , 0°  0\' 18"  W ' => array( -0.005, 
-0.005, 1 / 3600 ),
                        '55° 0′ 18″, 37° 0′ 18″' => array( 55.005, 37.005, 1 / 
3600 ),
+                       '55° 45\' 20.8296" 37° 37\' 3.4788"' => array( 
55.755786, 37.617633, 1 / 3600 * 0.0001 ),
+                       '55 ° 45 \' 20.8296 " -37 ° 37 \' 3.4788 "' => array( 
55.755786, -37.617633, 1 / 3600 * 0.0001 ),
+                       '-55 ° 45 \' 20.8296 " -37° 37\' 3.4788"' => array( 
-55.755786, -37.617633, 1 / 3600 * 0.0001 ),
+                       '55° 0′ 18″ 37° 0′ 18″' => array( 55.005, 37.005, 1 / 
3600 ),
                );
 
                foreach ( $valid as $value => $expected ) {
diff --git a/ValueParsers/tests/phpunit/parsers/FloatCoordinateParserTest.php 
b/ValueParsers/tests/phpunit/parsers/FloatCoordinateParserTest.php
index 758689f..21fdc41 100644
--- a/ValueParsers/tests/phpunit/parsers/FloatCoordinateParserTest.php
+++ b/ValueParsers/tests/phpunit/parsers/FloatCoordinateParserTest.php
@@ -57,6 +57,13 @@
                        '5.5S,37W ' => array( -5.5, -37, 0.1 ),
                        '-5.5,-37 ' => array( -5.5, -37, 0.1 ),
                        '4,2' => array( 4, 2, 1 ),
+                       '55.7557860 N 37.6176330 W' => array( 55.7557860, 
-37.6176330, 0.000001 ),
+                       '55.7557860 -37.6176330' => array( 55.7557860, 
-37.6176330, 0.000001 ),
+                       '55 S 37.6176330 W' => array( -55, -37.6176330, 
0.000001 ),
+                       '-55 -37.6176330' => array( -55, -37.6176330, 0.000001 
),
+                       '5.5S 37W ' => array( -5.5, -37, 0.1 ),
+                       '-5.5 -37 ' => array( -5.5, -37, 0.1 ),
+                       '4 2' => array( 4, 2, 1 ),
                );
 
                foreach ( $valid as $value => $expected ) {
diff --git a/ValueParsers/tests/phpunit/parsers/GeoCoordinateParserTest.php 
b/ValueParsers/tests/phpunit/parsers/GeoCoordinateParserTest.php
index 6585879..02b0f2e 100644
--- a/ValueParsers/tests/phpunit/parsers/GeoCoordinateParserTest.php
+++ b/ValueParsers/tests/phpunit/parsers/GeoCoordinateParserTest.php
@@ -58,6 +58,9 @@
                        '5.5S,37W ' => array( -5.5, -37, 0.1 ),
                        '-5.5,-37 ' => array( -5.5, -37, 0.1 ),
                        '4,2' => array( 4, 2, 1 ),
+                       '5.5S 37W ' => array( -5.5, -37, 0.1 ),
+                       '-5.5 -37 ' => array( -5.5, -37, 0.1 ),
+                       '4 2' => array( 4, 2, 1 ),
 
                        // DD
                        '55.7557860° N, 37.6176330° W' => array( 55.7557860, 
-37.6176330, 0.000001 ),
@@ -66,6 +69,9 @@
                        '-55°, -37.6176330 °' => array( -55, -37.6176330, 
0.000001 ),
                        '5.5°S,37°W ' => array( -5.5, -37, 0.1 ),
                        '-5.5°,-37° ' => array( -5.5, -37, 0.1 ),
+                       '-55° -37.6176330 °' => array( -55, -37.6176330, 
0.000001 ),
+                       '5.5°S 37°W ' => array( -5.5, -37, 0.1 ),
+                       '-5.5 ° -37 ° ' => array( -5.5, -37, 0.1 ),
 
                        // DMS
                        '55° 45\' 20.8296", 37° 37\' 3.4788"' => array( 
55.755786, 37.617633, 1 / 36000000 ),
@@ -79,6 +85,9 @@
                        '0° 0\' 18" N, 0° 0\' 18" E' => array( 0.005, 0.005, 1 
/ 3600 ),
                        ' 0° 0\' 18" S  , 0°  0\' 18"  W ' => array( -0.005, 
-0.005, 1 / 3600 ),
                        '0° 0′ 18″ N, 0° 0′ 18″ E' => array( 0.005, 0.005, 1 / 
3600 ),
+                       '0° 0\' 18" N  0° 0\' 18" E' => array( 0.005, 0.005, 1 
/ 3600 ),
+                       ' 0 ° 0 \' 18 " S   0 °  0 \' 18 "  W ' => array( 
-0.005, -0.005, 1 / 3600 ),
+                       '0° 0′ 18″ N 0° 0′ 18″ E' => array( 0.005, 0.005, 1 / 
3600 ),
 
                        // DM
                        '55° 0\', 37° 0\'' => array( 55, 37, 1 / 60 ),
@@ -87,6 +96,9 @@
                        '-55° 30\', -37° 30\'' => array( -55.5, -37.5, 1 / 60 ),
                        '0° 0.3\' S, 0° 0.3\' W' => array( -0.005, -0.005, 1 / 
3600 ),
                        '-55° 30′, -37° 30′' => array( -55.5, -37.5, 1 / 60 ),
+                       '-55 ° 30 \' -37 ° 30 \'' => array( -55.5, -37.5, 1 / 
60 ),
+                       '0° 0.3\' S 0° 0.3\' W' => array( -0.005, -0.005, 1 / 
3600 ),
+                       '-55° 30′ -37° 30′' => array( -55.5, -37.5, 1 / 60 ),
                );
 
                foreach ( $valid as $value => $expected ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/69630
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id89dcf80e84a9d1867046bc251185fd0d47e067c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to