Daniel Kinzler has uploaded a new change for review.

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


Change subject: (bug 49832) i18n for value errors.
......................................................................

(bug 49832) i18n for value errors.

This introduces the notion of abstract error codes and a mapping
to an i18n mechanism.

Change-Id: Id053c35287624e21fbd13bc6d7e791cf621e1cfa
---
M DataValues/DataValues.classes.php
M DataValues/DataValues.i18n.php
M DataValues/includes/DataValueFactory.php
M DataValues/includes/DataValueObject.php
A DataValues/includes/FieldOutOfRangeException.php
M DataValues/includes/IllegalValueException.php
A DataValues/includes/MalformedFieldValueException.php
A DataValues/includes/MissingDataFieldException.php
A DataValues/includes/UnexpectedFieldTypeException.php
A DataValues/includes/UnsupportedFieldValueException.php
A DataValues/includes/ValueError.php
A DataValues/includes/ValueErrorCodeMapper.php
M DataValues/includes/values/BooleanValue.php
M DataValues/includes/values/GeoCoordinateValue.php
M DataValues/includes/values/IriValue.php
M DataValues/includes/values/MonolingualTextValue.php
M DataValues/includes/values/MultilingualTextValue.php
M DataValues/includes/values/NumberValue.php
M DataValues/includes/values/QuantityValue.php
M DataValues/includes/values/StringValue.php
M DataValues/includes/values/TimeValue.php
A DataValues/tests/phpunit/includes/ValueErrorCodeMapperTest.php
22 files changed, 668 insertions(+), 43 deletions(-)


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

diff --git a/DataValues/DataValues.classes.php 
b/DataValues/DataValues.classes.php
index d364ef7..94bc321 100644
--- a/DataValues/DataValues.classes.php
+++ b/DataValues/DataValues.classes.php
@@ -42,7 +42,14 @@
        'DataValues\DataValueFactory' => 'includes/DataValueFactory.php',
        'DataValues\DataValueObject' => 'includes/DataValueObject.php',
 
+       'DataValues\FieldOutOfRangeException' => 
'includes/FieldOutOfRangeException.php',
        'DataValues\IllegalValueException' => 
'includes/IllegalValueException.php',
+       'DataValues\MalformedFieldValueException' => 
'includes/MalformedFieldValueException.php',
+       'DataValues\MissingDataFieldException' => 
'includes/MissingDataFieldException.php',
+       'DataValues\UnsupportedFieldValueException' => 
'includes/UnsupportedFieldValueException.php',
+       'DataValues\UnexpectedFieldTypeException' => 
'includes/UnexpectedFieldTypeException.php',
+       'DataValues\ValueError' => 'includes/ValueError.php',
+       'DataValues\ValueErrorCodeMapper' => 
'includes/ValueErrorCodeMapper.php',
 
        'Comparable' => 'includes/Comparable.php',
        'Copyable' => 'includes/Copyable.php',
diff --git a/DataValues/DataValues.i18n.php b/DataValues/DataValues.i18n.php
index b28c2a4..624e491 100644
--- a/DataValues/DataValues.i18n.php
+++ b/DataValues/DataValues.i18n.php
@@ -35,6 +35,13 @@
 $messages['en'] = array(
        'datavalues-desc' => 'Collection of objects representing various kinds 
of values',
        'version-datavalues' => 'DataValues',
+
+       'datavalues-error-value-out-of-range' => '$1 is out of range: should be 
between $2 and $3, but is $4',
+       'datavalues-error-malformed-field-value' => '$1 is malformed: $2',
+       'datavalues-error-missing-data-field' => 'Missing field: $1',
+       'datavalues-error-unexpected-field-type' => '$1 has unexpected type $3, 
expected $2',
+       'datavalues-error-unsupported-field-value' => '$1 has an unsupported 
value: $2',
+       'datavalues-error-duplicate-language' => 'Language code $1 is present 
more than once.'
 );
 
 /** Message documentation (Message documentation)
@@ -43,6 +50,47 @@
 $messages['qqq'] = array(
        'datavalues-desc' => '{{desc|name=Data 
Values|url=http://www.mediawiki.org/wiki/Extension:DataValues}}',
        'version-datavalues' => 'Name of the DataValues extension collection, 
used on [[Special:Version]]',
+
+       'datavalues-error-value-out-of-range' => 'An error message indicating 
that a given value is out of range.
+
+Parameters:
+* $1 is the name of the field that is out of range
+* $2 is the minimal expected value
+* $3 is the maximal expected value
+* $4 is the actual value',
+
+       'datavalues-error-malformed-field-value' => 'An error message 
indicating that a given value is malformed
+
+Parameters:
+* $1 is the name of the field
+* $2 is the bad type
+',
+
+       'datavalues-error-missing-data-field' => 'An error message indicating 
that a given field is missing
+
+Parameters:
+* $1 is the name of the missing field
+',
+
+       'datavalues-error-unexpected-field-type' => 'An error message 
indicating that a given field has an unexpected type
+
+Parameters:
+* $1 is the name of the field
+* $2 is the bad type
+',
+
+       'datavalues-error-unsupported-field-value' => 'An error message 
indicating that a given value is unsupported
+
+Parameters:
+* $1 is the name of the field
+* $2 is the bad value
+',
+
+       'datavalues-error-duplicate-language' => 'An error message indicating 
that a language code is used multiple times
+
+Parameters:
+* $1 the lkanguage code
+',
 );
 
 /** Afrikaans (Afrikaans)
diff --git a/DataValues/includes/DataValueFactory.php 
b/DataValues/includes/DataValueFactory.php
index e2ace8d..5ac3c09 100644
--- a/DataValues/includes/DataValueFactory.php
+++ b/DataValues/includes/DataValueFactory.php
@@ -116,11 +116,11 @@
         */
        public function newFromArray( array $data ) {
                if ( !array_key_exists( 'type', $data ) ) {
-                       throw new IllegalValueException( 'DataValue type is 
missing' );
+                       throw new MissingDataFieldException( 'type' );
                }
 
                if ( !array_key_exists( 'value', $data ) ) {
-                       throw new IllegalValueException( 'DataValue value is 
missing' );
+                       throw new MissingDataFieldException( 'value' );
                }
 
                return $this->newDataValue( $data['type'], $data['value'] );
diff --git a/DataValues/includes/DataValueObject.php 
b/DataValues/includes/DataValueObject.php
index 9f9d162..7c62da3 100644
--- a/DataValues/includes/DataValueObject.php
+++ b/DataValues/includes/DataValueObject.php
@@ -103,12 +103,12 @@
         */
        protected static function requireArrayFields( $data, array $fields ) {
                if ( !is_array( $data ) ) {
-                       throw new IllegalValueException( "array expected" );
+                       throw new UnexpectedTypeException( 'array', $data );
                }
 
                foreach ( $fields as $field ) {
                        if ( !array_key_exists( $field, $data ) ) {
-                               throw new IllegalValueException( "$field field 
required" );
+                               throw new MissingDataFieldException( $field );
                        }
                }
        }
diff --git a/DataValues/includes/FieldOutOfRangeException.php 
b/DataValues/includes/FieldOutOfRangeException.php
new file mode 100644
index 0000000..ff9918f
--- /dev/null
+++ b/DataValues/includes/FieldOutOfRangeException.php
@@ -0,0 +1,60 @@
+<?php
+ /**
+ *
+ * Copyright © 19.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup DataValue
+ *
+ * @license GPL 2+
+ * @file
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace DataValues;
+
+
+use RuntimeException;
+
+/**
+ * Class FieldOutOfRangeException is thrown to indicate that some field in the
+ * native representation of a DataValue is out of range.
+ *
+ * @package DataValues
+ * @since 0.1
+ */
+class FieldOutOfRangeException extends IllegalValueException {
+
+       /**
+        * @param string     $field
+        * @param int|float  $min
+        * @param int|float  $max
+        * @param int|float  $actual
+        * @param \Exception $previous
+        *
+        * @internal param string $malformedValue
+        */
+       public function __construct( $field, $min, $max, $actual, \Exception 
$previous = null ) {
+               parent::__construct(
+                       "$field is out of range: should be between $min and 
$max, but is $actual",
+                       'value-out-of-range',
+                       array( $field, $min, $max, $actual ),
+                       $previous );
+       }
+}
\ No newline at end of file
diff --git a/DataValues/includes/IllegalValueException.php 
b/DataValues/includes/IllegalValueException.php
index e166458..e27d80c 100644
--- a/DataValues/includes/IllegalValueException.php
+++ b/DataValues/includes/IllegalValueException.php
@@ -28,12 +28,41 @@
 namespace DataValues;
 
 
-use InvalidArgumentException;
+use RuntimeException;
 
 /**
- * Class IllegalValueException
+ * Class IllegalValueException represents an error that arises when 
constructing a DataValue object.
+ * It is typically thrown by the constructor or newFromArray() method of a 
DataValue subclass
+ * to indicate that the supplied data is not compliant with the expectations 
of that kind of
+ * DataValue.
+ *
  * @package DataValues
  */
-class IllegalValueException extends InvalidArgumentException {
+class IllegalValueException extends RuntimeException {
+
+       /**
+        * @var ValueError
+        */
+       protected $error;
+
+       /**
+        * @param string  $message
+        * @param string  $code
+        * @param array   $params
+        * @param \Exception $previous
+        */
+       public function __construct( $message, $code = null, $params = array(), 
\Exception $previous = null ) {
+               parent::__construct( $message, 0, $previous );
+
+               if ( $code === null ) {
+                       $this->error = null; //TODO: B/C only! Make this an 
error soon!
+               } else {
+                       $this->error = new ValueError( $code, $params );
+               }
+       }
+
+       public function getValueError() {
+               return $this->error;
+       }
 
 }
\ No newline at end of file
diff --git a/DataValues/includes/MalformedFieldValueException.php 
b/DataValues/includes/MalformedFieldValueException.php
new file mode 100644
index 0000000..7d97228
--- /dev/null
+++ b/DataValues/includes/MalformedFieldValueException.php
@@ -0,0 +1,56 @@
+<?php
+ /**
+ *
+ * Copyright © 19.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup DataValue
+ *
+ * @license GPL 2+
+ * @file
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace DataValues;
+
+
+use RuntimeException;
+
+/**
+ * Class MalformedFieldValueException is thrown to indicate that some field in 
the
+ * native representation of a DataValue is syntactically malformed.
+ *
+ * @package DataValues
+ * @since 0.1
+ */
+class MalformedFieldValueException extends IllegalValueException {
+
+       /**
+        * @param string     $field
+        * @param string     $malformedValue
+        * @param \Exception $previous
+        */
+       public function __construct( $field, $malformedValue, \Exception 
$previous = null ) {
+               parent::__construct(
+                       "$field is malformed: $malformedValue",
+                       'malformed-field-value',
+                       array( $field, $malformedValue ),
+                       $previous );
+       }
+}
\ No newline at end of file
diff --git a/DataValues/includes/MissingDataFieldException.php 
b/DataValues/includes/MissingDataFieldException.php
new file mode 100644
index 0000000..2cf3a3a
--- /dev/null
+++ b/DataValues/includes/MissingDataFieldException.php
@@ -0,0 +1,55 @@
+<?php
+ /**
+ *
+ * Copyright © 07.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup DataValue
+ *
+ * @license GPL 2+
+ * @file
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace DataValues;
+
+
+use RuntimeException;
+
+/**
+ * Class MissingDataFieldException is thrown to indicate that the native 
(array) representation of
+ * a DataValue is missing a field.
+ *
+ * @package DataValues
+ * @since 0.1
+ */
+class MissingDataFieldException extends IllegalValueException {
+
+       /**
+        * @param string     $missingField
+        * @param \Exception $previous
+        */
+       public function __construct( $missingField, \Exception $previous = null 
) {
+               parent::__construct(
+                       "Missing field: $missingField",
+                       'missing-data-field',
+                       array( $missingField ),
+                       $previous );
+       }
+}
\ No newline at end of file
diff --git a/DataValues/includes/UnexpectedFieldTypeException.php 
b/DataValues/includes/UnexpectedFieldTypeException.php
new file mode 100644
index 0000000..a69ac86
--- /dev/null
+++ b/DataValues/includes/UnexpectedFieldTypeException.php
@@ -0,0 +1,63 @@
+<?php
+ /**
+ *
+ * Copyright © 19.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup DataValue
+ *
+ * @license GPL 2+
+ * @file
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace DataValues;
+
+
+use RuntimeException;
+
+/**
+ * Class UnexpectedFieldTypeException is thrown to indicate that some part of 
the native
+ * representation of a DataValue has the wrong type.
+ *
+ * @package DataValues
+ * @since 0.1
+ */
+class UnexpectedFieldTypeException extends IllegalValueException {
+
+       /**
+        * @param string     $field
+        * @param string     $expectedType
+        * @param mixed      $actualValue
+        * @param \Exception $previous
+        */
+       public function __construct( $field, $expectedType, $actualValue, 
\Exception $previous = null ) {
+               if ( is_object( $actualValue ) ) {
+                       $actualType = get_class( $actualValue );
+               } else {
+                       $actualType = gettype( $actualValue );
+               }
+
+               parent::__construct(
+                       "$field has unexpected type $actualType, expected 
$expectedType",
+                       'unexpected-field-type',
+                       array( $field, $expectedType, $actualType ),
+                       $previous );
+       }
+}
\ No newline at end of file
diff --git a/DataValues/includes/UnsupportedFieldValueException.php 
b/DataValues/includes/UnsupportedFieldValueException.php
new file mode 100644
index 0000000..ab40acd
--- /dev/null
+++ b/DataValues/includes/UnsupportedFieldValueException.php
@@ -0,0 +1,56 @@
+<?php
+ /**
+ *
+ * Copyright © 19.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup DataValue
+ *
+ * @license GPL 2+
+ * @file
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace DataValues;
+
+
+use RuntimeException;
+
+/**
+ * Class UnsupportedFieldValueException is thrown to indicate that some field 
in the
+ * native representation of a DataValue is syntactically malformed.
+ *
+ * @package DataValues
+ * @since 0.1
+ */
+class UnsupportedFieldValueException extends IllegalValueException {
+
+       /**
+        * @param string     $field
+        * @param mixed      $unsupportedValue
+        * @param \Exception $previous
+        */
+       public function __construct( $field, $unsupportedValue, \Exception 
$previous = null ) {
+               parent::__construct(
+                       "$field has an unsupported value: $unsupportedValue",
+                       'unsupported-field-value',
+                       array( $field, $unsupportedValue ),
+                       $previous );
+       }
+}
\ No newline at end of file
diff --git a/DataValues/includes/ValueError.php 
b/DataValues/includes/ValueError.php
new file mode 100644
index 0000000..09cf344
--- /dev/null
+++ b/DataValues/includes/ValueError.php
@@ -0,0 +1,83 @@
+<?php
+ /**
+ *
+ * Copyright © 19.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup DataValue
+ *
+ * @license GPL 2+
+ * @file
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace DataValues;
+
+
+use Immutable;
+
+/**
+ * Class ValueError
+ * @package DataValues
+ * @since 0.1
+ */
+class ValueError implements Immutable {
+
+       /**
+        * @var string
+        */
+       protected $code;
+
+       /**
+        * @var string[]
+        */
+       protected $parameters;
+
+       /**
+        * @param string $code
+        * @param string $parameter,...
+        */
+       public function __construct( $code ) {
+               $args = func_get_args();
+
+               if ( count( $args ) === 2 && is_array( $args[1] ) ) {
+                       $args = $args[1];
+               } else {
+                       $args = array_slice( $args, 1 );
+               }
+
+               $this->code;
+               $this->parameters = $args;
+       }
+
+       /**
+        * @return string
+        */
+       public function getCode() {
+               return $this->code;
+       }
+
+       /**
+        * @return string[]
+        */
+       public function getParameters() {
+               return $this->parameters;
+       }
+
+}
\ No newline at end of file
diff --git a/DataValues/includes/ValueErrorCodeMapper.php 
b/DataValues/includes/ValueErrorCodeMapper.php
new file mode 100644
index 0000000..5e522a4
--- /dev/null
+++ b/DataValues/includes/ValueErrorCodeMapper.php
@@ -0,0 +1,89 @@
+<?php
+ /**
+ *
+ * Copyright © 19.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup DataValue
+ *
+ * @license GPL 2+
+ * @file
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace DataValues;
+
+
+use Immutable;
+
+/**
+ * Class ValueErrorCodeMapper provides a mapping from error code as used with 
ValueError objects
+ * and message keys as used in DataValues.i18n.php.
+ *
+ * @package DataValues
+ * @since 0.1
+ */
+class ValueErrorCodeMapper {
+
+       protected $i18nFunction;
+
+       /**
+        * @param callable|null $i18nFunction
+        */
+       public function __construct( $i18nFunction = null ) {
+               if ( !is_null( $i18nFunction ) && !is_callable( $i18nFunction ) 
) {
+                       throw new \InvalidArgumentException( "The 
internationalization callback must be callable" );
+               }
+
+               $this->i18nFunction = $i18nFunction;
+       }
+
+       /**
+        * Returns the message key used for the given error in the 
internationalization file.
+        *
+        * @param $errorCode
+        *
+        * @return string
+        */
+       public function getMessageKey( $errorCode ) {
+               return 'datavalues-error-' . $errorCode;
+       }
+
+       /**
+        * Returns the message defined for the given error in the 
internationalization file.
+        * This uses the callback function provided to the constructor.
+        *
+        * @param string $errorCode
+        * @param array  $params
+        *
+        * @return mixed The message, as a string or some kind of message 
object (or the error code
+        *         itself if no callback was provided to the constructor).
+        */
+       public function getMessage( $errorCode, array $params = array() ) {
+               if ( $this->i18nFunction === null ) {
+                       return $errorCode;
+               }
+
+               $key = $this->getMessageKey( $errorCode );
+               $message = call_user_func( $this->i18nFunction, $key, $params );
+
+               return $message;
+       }
+
+}
\ No newline at end of file
diff --git a/DataValues/includes/values/BooleanValue.php 
b/DataValues/includes/values/BooleanValue.php
index cf914ab..540e280 100644
--- a/DataValues/includes/values/BooleanValue.php
+++ b/DataValues/includes/values/BooleanValue.php
@@ -46,7 +46,7 @@
         */
        public function __construct( $value ) {
                if ( !is_bool( $value ) ) {
-                       throw new IllegalValueException( 'Can only construct 
BooleanValue from booleans' );
+                       throw new UnexpectedFieldTypeException( '$value', 
'bool', $value );
                }
 
                $this->value = $value;
diff --git a/DataValues/includes/values/GeoCoordinateValue.php 
b/DataValues/includes/values/GeoCoordinateValue.php
index 61eec4d..08e20fa 100644
--- a/DataValues/includes/values/GeoCoordinateValue.php
+++ b/DataValues/includes/values/GeoCoordinateValue.php
@@ -105,23 +105,23 @@
                }
 
                if ( !is_float( $latitude ) ) {
-                       throw new IllegalValueException( 'Can only construct 
GeoCoordinateValue with a numeric latitude' );
+                       throw new UnexpectedFieldTypeException( '$latitude', 
'float', $latitude );
                }
 
                if ( !is_float( $longitude ) ) {
-                       throw new IllegalValueException( 'Can only construct 
GeoCoordinateValue with a numeric longitude' );
+                       throw new UnexpectedFieldTypeException( '$longitude', 
'float', $longitude );
                }
 
                if ( $altitude !== null && !is_float( $altitude ) ) {
-                       throw new IllegalValueException( 'Can only construct 
GeoCoordinateValue with a numeric altitude' );
+                       throw new UnexpectedFieldTypeException( '$altitude', 
'float', $altitude );
                }
 
                if ( $precision !== null && !is_float( $precision ) ) {
-                       throw new IllegalValueException( 'Can only construct 
GeoCoordinateValue with a numeric precision' );
+                       throw new UnexpectedFieldTypeException( '$precision', 
'float', $precision );
                }
 
                if ( !is_string( $globe ) && $globe !== null ) {
-                       throw new IllegalValueException( 'Can only construct 
GeoCoordinateValue with a string or null globe parameter' );
+                       throw new UnexpectedFieldTypeException( '$globe', 
'string', $globe );
                }
 
                $this->latitude = $latitude;
diff --git a/DataValues/includes/values/IriValue.php 
b/DataValues/includes/values/IriValue.php
index 61b1628..3002ca8 100644
--- a/DataValues/includes/values/IriValue.php
+++ b/DataValues/includes/values/IriValue.php
@@ -2,6 +2,8 @@
 
 namespace DataValues;
 
+use InvalidArgumentException;
+
 /**
  * Class representing a IRI value.
  *
@@ -89,18 +91,28 @@
         * @throws IllegalValueException
         */
        public function __construct( $scheme, $hierarchicalPart, $query = '', 
$fragment = '' ) {
-               foreach ( func_get_args() as $value ) {
-                       if ( !is_string( $value ) ) {
-                               throw new IllegalValueException( 'Can only 
construct IriValue from strings' );
-                       }
+               if ( !is_string( $scheme ) ) {
+                       throw new UnexpectedFieldTypeException( '$scheme', 
'string', $scheme );
+               }
+
+               if ( !is_string( $hierarchicalPart ) ) {
+                       throw new UnexpectedFieldTypeException( 
'$hierarchicalPart', 'string', $hierarchicalPart );
+               }
+
+               if ( !is_string( $query ) ) {
+                       throw new UnexpectedFieldTypeException( '$query', 
'string', $query );
+               }
+
+               if ( !is_string( $fragment ) ) {
+                       throw new UnexpectedFieldTypeException( '$fragment', 
'string', $fragment );
                }
 
                if ( $scheme === '' || preg_match( '/[^a-zA-Z]/u', $scheme ) ) {
-                       throw new IllegalValueException( "Illegal URI scheme 
'$scheme'." );
+                       throw new MalformedFieldValueException( '$scheme', 
$scheme );
                }
 
                if ( $hierarchicalPart === '' ) {
-                       throw new IllegalValueException( "Illegal URI 
hierarchical part '$hierarchicalPart'." );
+                       throw new MalformedFieldValueException( 
'$hierarchicalPart', $hierarchicalPart );
                }
 
                $this->scheme = $scheme;
@@ -223,17 +235,17 @@
         * @param string $serialization
         *
         * @return array
-        * @throws IllegalValueException
+        * @throws InvalidArgumentException
         */
        public static function getIriParts( $serialization ) {
                if ( !is_string( $serialization ) ) {
-                       throw new IllegalValueException( 'IriValue::getIriParts 
expects a string value' );
+                       throw new \InvalidArgumentException( '$serialization 
must be a string' );
                }
 
                $parts = explode( ':', $serialization, 2 ); // try to split 
"schema:rest"
 
                if ( count( $parts ) === 1 ) {
-                       throw new IllegalValueException( "Unserialization 
failed: the string \"$serialization\" is no valid URI." );
+                       throw new \InvalidArgumentException( "Unserialization 
failed: the string \"$serialization\" is no valid URI." );
                }
 
                $scheme = $parts[0];
diff --git a/DataValues/includes/values/MonolingualTextValue.php 
b/DataValues/includes/values/MonolingualTextValue.php
index c9ca785..a7f1775 100644
--- a/DataValues/includes/values/MonolingualTextValue.php
+++ b/DataValues/includes/values/MonolingualTextValue.php
@@ -58,14 +58,14 @@
         */
        public function __construct( $languageCode, $value ) {
                if ( !is_string( $languageCode ) ) {
-                       throw new IllegalValueException( 'Can only construct 
MonolingualTextValue with a string language code' );
+                       throw new UnexpectedFieldTypeException( 
'$languageCode', 'string', $languageCode );
                }
                elseif ( $languageCode === '' ) {
-                       throw new IllegalValueException( 'Can only construct 
MonolingualTextValue with a language code of non-zero length' );
+                       throw new MalformedFieldValueException( 
'$languageCode', $languageCode );
                }
 
                if ( !is_string( $value ) ) {
-                       throw new IllegalValueException( 'Can only construct 
MonolingualTextValue with a string value' );
+                       throw new UnexpectedFieldTypeException( '$value', 
'string', $value );
                }
 
                $this->value = $value;
diff --git a/DataValues/includes/values/MultilingualTextValue.php 
b/DataValues/includes/values/MultilingualTextValue.php
index db54d94..a77cacf 100644
--- a/DataValues/includes/values/MultilingualTextValue.php
+++ b/DataValues/includes/values/MultilingualTextValue.php
@@ -49,13 +49,17 @@
        public function __construct( array $monolingualValues ) {
                foreach ( $monolingualValues as $monolingualValue ) {
                        if ( !( $monolingualValue instanceof 
MonolingualTextValue ) ) {
-                               throw new IllegalValueException( 'Can only 
construct MultilingualTextValue from MonolingualTextValue objects' );
+                               throw new UnexpectedFieldTypeException( 
'$monolingualValues', 'DataValues\MonolingualTextValue', $monolingualValue );
                        }
 
                        $langCode = $monolingualValue->getLanguageCode();
 
                        if ( array_key_exists( $langCode, $this->texts ) ) {
-                               throw new IllegalValueException( 'Can only add 
a single MonolingualTextValue per language to a MultilingualTextValue' );
+                               throw new IllegalValueException(
+                                       'Can only add a single 
MonolingualTextValue per language to a MultilingualTextValue',
+                                       'duplicate-language',
+                                       array( $langCode )
+                               );
                        }
 
                        $this->texts[$langCode] = $monolingualValue;
@@ -165,7 +169,7 @@
         */
        public static function newFromArray( $data ) {
                if ( !is_array( $data ) ) {
-                       throw new IllegalValueException( "array expected" );
+                       throw new UnexpectedFieldTypeException( '$data', 
"array", $data );
                }
 
                $values = array();
diff --git a/DataValues/includes/values/NumberValue.php 
b/DataValues/includes/values/NumberValue.php
index 27d7361..41541bd 100644
--- a/DataValues/includes/values/NumberValue.php
+++ b/DataValues/includes/values/NumberValue.php
@@ -49,7 +49,7 @@
         */
        public function __construct( $value ) {
                if ( !is_int( $value ) && !is_float( $value ) ) {
-                       throw new IllegalValueException( 'Can only construct 
NumberValue from floats or integers' );
+                       throw new UnexpectedFieldTypeException( '$value', 
'int|float', $value );
                }
 
                $this->value = $value;
diff --git a/DataValues/includes/values/QuantityValue.php 
b/DataValues/includes/values/QuantityValue.php
index c461ee1..f7c1aad 100644
--- a/DataValues/includes/values/QuantityValue.php
+++ b/DataValues/includes/values/QuantityValue.php
@@ -64,15 +64,15 @@
         */
        public function __construct( $amount, $unit = null, $accuracy = null ) {
                if ( !is_int( $amount ) && !is_float( $amount ) ) {
-                       throw new IllegalValueException( 'Can only construct 
QuantityValue from floats or integers' );
+                       throw new UnexpectedFieldTypeException( '$amount', 
'int|float', $amount );
                }
 
                if ( $accuracy !== null && !is_int( $accuracy ) && !is_float( 
$accuracy ) ) {
-                       throw new IllegalValueException( 'The accuracy of a 
QuantityValue needs to be a float or integer' );
+                       throw new UnexpectedFieldTypeException( '$accuracy', 
'int|float', $accuracy );
                }
 
                if ( $unit !== null && !is_string( $unit ) ) {
-                       throw new IllegalValueException( 'The unit of a 
QuantityValue needs to be a string' );
+                       throw new UnexpectedFieldTypeException( '$unit', 
'int|float', $unit );
                }
 
                $this->value = $amount;
diff --git a/DataValues/includes/values/StringValue.php 
b/DataValues/includes/values/StringValue.php
index ce8ac84..a057120 100644
--- a/DataValues/includes/values/StringValue.php
+++ b/DataValues/includes/values/StringValue.php
@@ -46,7 +46,7 @@
         */
        public function __construct( $value ) {
                if ( !is_string( $value ) ) {
-                       throw new IllegalValueException( 'Can only construct 
StringValue from strings' );
+                       throw new UnexpectedFieldTypeException( '$value', 
'string', $value );
                }
 
                $this->value = $value;
diff --git a/DataValues/includes/values/TimeValue.php 
b/DataValues/includes/values/TimeValue.php
index ecd933a..a1912c7 100644
--- a/DataValues/includes/values/TimeValue.php
+++ b/DataValues/includes/values/TimeValue.php
@@ -118,35 +118,43 @@
         */
        public function __construct( $time, $timezone, $before, $after, 
$precision, $calendarModel ) {
                if ( !is_string( $time ) ) {
-                       throw new IllegalValueException( '$time needs to be a 
string' );
+                       throw new UnexpectedFieldTypeException( '$time', 
'string', $time );
                }
 
                if ( !is_integer( $timezone ) ) {
-                       throw new IllegalValueException( '$timezone needs to be 
an integer' );
+                       throw new UnexpectedFieldTypeException( '$timezone', 
'string', $timezone );
                }
 
                if ( $timezone < -12 * 3600 || $timezone > 14 * 3600 ) {
-                       throw new IllegalValueException( '$timezone out of 
allowed bounds' );
+                       throw new FieldOutOfRangeException( '$timezone', -12 * 
3600, 14 * 3600, $timezone );
                }
 
-               if ( !is_integer( $before ) || $before < 0 ) {
-                       throw new IllegalValueException( '$before needs to be 
an unsigned integer' );
+               if ( !is_integer( $before ) ) {
+                       throw new UnexpectedFieldTypeException( '$before', 
'string', $before );
                }
 
-               if ( !is_integer( $after ) || $after < 0 ) {
-                       throw new IllegalValueException( '$after needs to be an 
unsigned integer' );
+               if ( $before < 0 ) {
+                       throw new FieldOutOfRangeException( '$before', 0, 
PHP_INT_MAX, $timezone );
+               }
+
+               if ( !is_integer( $after ) ) {
+                       throw new UnexpectedFieldTypeException( '$after', 
'string', $after );
+               }
+
+               if ( $after < 0 ) {
+                       throw new FieldOutOfRangeException( '$after', 0, 
PHP_INT_MAX, $timezone );
                }
 
                if ( !is_integer( $precision ) ) {
-                       throw new IllegalValueException( '$precision needs to 
be an integer' );
+                       throw new UnexpectedFieldTypeException( '$precision', 
'int', $precision );
                }
 
                if ( $precision < self::PRECISION_Ga || $precision > 
self::PRECISION_SECOND ) {
-                       throw new IllegalValueException( '$precision out of 
allowed bounds' );
+                       throw new FieldOutOfRangeException( '$calendarModel', 
self::PRECISION_Ga, self::PRECISION_SECOND, $calendarModel );
                }
 
                if ( !is_string( $calendarModel ) ) {
-                       throw new IllegalValueException( '$calendarModel needs 
to be a string' );
+                       throw new UnexpectedFieldTypeException( 
'$calendarModel', 'string', $calendarModel );
                }
 
                // Can haz scalar type hints plox? ^^
diff --git a/DataValues/tests/phpunit/includes/ValueErrorCodeMapperTest.php 
b/DataValues/tests/phpunit/includes/ValueErrorCodeMapperTest.php
new file mode 100644
index 0000000..45d6b05
--- /dev/null
+++ b/DataValues/tests/phpunit/includes/ValueErrorCodeMapperTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace DataValues\Test;
+
+use DataValues\DataValueFactory;
+use DataValues\ValueErrorCodeMapper;
+
+/**
+ * Tests for the DataValues\ValueErrorCodeMapper class.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.1
+ *
+ * @ingroup DataValueTest
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class ValueErrorCodeMapperTest extends \PHPUnit_Framework_TestCase {
+
+       public function testGetMessageKey() {
+               $mapper = new ValueErrorCodeMapper();
+
+               $this->assertEquals( 'datavalues-error-foo', 
$mapper->getMessageKey( 'foo' ), 'message key' );
+       }
+
+       public function testGetMessage() {
+               $mapper = new ValueErrorCodeMapper();
+               $this->assertEquals( 'foo', $mapper->getMessage( 'foo' ), 'fall 
back to error code' );
+
+               $mapper = new ValueErrorCodeMapper( function( $s ) {
+                       return strtoupper( $s );
+               } );
+
+               $this->assertEquals( 'DATAVALUES-ERROR-FOO', 
$mapper->getMessage( 'foo' ), 'with callback' );
+       }
+
+}
\ No newline at end of file

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id053c35287624e21fbd13bc6d7e791cf621e1cfa
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>

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

Reply via email to