jenkins-bot has submitted this change and it was merged.

Change subject: [time.js] added time.Time.validate and use it in time.Time 
constructor
......................................................................


[time.js] added time.Time.validate and use it in time.Time constructor

time.Time.validate checks whether a given plain object representing a time 
makes sense. If not, an
error will be thrown.

Change-Id: I1431c9f9bdeff711713a4f5c56ae8b1c63bcb533
---
M DataValues/DataValues.resources.php
M DataValues/DataValues.tests.qunit.php
M DataValues/resources/time.js/src/time.Time.js
A DataValues/resources/time.js/src/time.Time.validate.js
A DataValues/resources/time.js/tests/time.Time.validate.tests.js
5 files changed, 238 insertions(+), 2 deletions(-)

Approvals:
  Henning Snater: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/DataValues/DataValues.resources.php 
b/DataValues/DataValues.resources.php
index 9174296..b4038df 100644
--- a/DataValues/DataValues.resources.php
+++ b/DataValues/DataValues.resources.php
@@ -90,6 +90,7 @@
                        'scripts' => array(
                                'time.js/src/time.js',
                                'time.js/src/time.Time.js',
+                               'time.js/src/time.Time.validate.js',
                                'time.js/src/time.Time.parse.js',
                        ),
                        'dependencies' => array(
diff --git a/DataValues/DataValues.tests.qunit.php 
b/DataValues/DataValues.tests.qunit.php
index 758fe2a..c574dd4 100644
--- a/DataValues/DataValues.tests.qunit.php
+++ b/DataValues/DataValues.tests.qunit.php
@@ -85,6 +85,7 @@
                                
'resources/time.js/tests/time.Time.knowsPrecision.tests.js',
                                
'resources/time.js/tests/time.Time.minPrecision.tests.js',
                                
'resources/time.js/tests/time.Time.maxPrecision.tests.js',
+                               
'resources/time.js/tests/time.Time.validate.tests.js',
                        ),
                        'dependencies' => array(
                                'time.js',
diff --git a/DataValues/resources/time.js/src/time.Time.js 
b/DataValues/resources/time.js/src/time.Time.js
index f6839d8..2fcfed6 100644
--- a/DataValues/resources/time.js/src/time.Time.js
+++ b/DataValues/resources/time.js/src/time.Time.js
@@ -25,6 +25,8 @@
         *        precision.
         *        {string} calendarname: Default calendar name overruling the 
automatically detected
         *        calendar.
+        *
+        * @throws {Error} If given time Definition is an Object not 
representing a valid time.
         */
        var Time = function Time( timeDefinition, options ) {
                var result;
@@ -35,9 +37,10 @@
                }, options );
 
                if( typeof timeDefinition === 'string' ) {
-                       result = time.Time.parse( timeDefinition );
+                       result = Time.parse( timeDefinition );
                } else {
-                       result = $.extend( {}, timeDefinition );
+                       result = $.extend( {}, timeDefinition ); // copy object
+                       Time.validate( result );
                }
                if( result === null ) {
                        result = {};
diff --git a/DataValues/resources/time.js/src/time.Time.validate.js 
b/DataValues/resources/time.js/src/time.Time.validate.js
new file mode 100644
index 0000000..79d1a2d
--- /dev/null
+++ b/DataValues/resources/time.js/src/time.Time.validate.js
@@ -0,0 +1,79 @@
+/**
+ * time.Time.validate for validating structures passed to the time.Time 
constructor.
+ *
+ * @since 0.1
+ * @file
+ * @ingroup Time.js
+ * @licence GNU GPL v2+
+ *
+ * @author Daniel Werner < daniel.wer...@wikimedia.de >
+ */
+time.Time.validate = ( function( Time ) {
+       'use strict';
+
+       /**
+        * Makes sure a given time structure is valid. If not, an Error will be 
thrown.
+        *
+        * @param {Object} definition
+        * @throws {Error}
+        */
+       return function validateTimeDefinition( definition ) {
+               validateFieldTypes( definition, {
+                       day: 'number',
+                       month: 'number',
+                       year: 'number',
+                       calendarname: 'string',
+                       precision: 'number'
+               } );
+
+               if( definition.year === undefined || isNaN( definition.year ) ) 
{
+                       throw new Error( '"year" has to be a number' );
+               }
+
+               if( definition.month > 12 || definition.month < 1 ) {
+                       throw new Error( '"month" must not be lower than 1 
(January) or higher than 12 ' +
+                               '(December). "' + definition.month + '" is not 
a valid month number.'  );
+               }
+
+               if( definition.day < 1 ) {
+                       throw new Error( '"day" must not be lower than 1' );
+               }
+               // TODO: Add check for last day of the month once we have one 
validator per calendar model.
+
+               // TODO: remove the following check once we have one validator 
per calendar model:
+               if( definition.calendarname !== Time.CALENDAR.GREGORIAN
+                       && definition.calendarname !== Time.CALENDAR.JULIAN
+               ) {
+                       throw new Error( '"calendarname" is "' + 
definition.calendarname + '" but has to be "'
+                               + Time.CALENDAR.GREGORIAN + '" or "' + 
Time.CALENDAR.JULIAN + '"' );
+               }
+
+               if( !Time.knowsPrecision( definition.precision ) ) {
+                       throw new Error( 'Unknown precision "' + 
definition.precision + '" given in "precision"' );
+               }
+       };
+
+       /**
+        * Checks a definition for certain fields. If the field is available, 
an error will be thrown
+        * in case the field is not of the specified type.
+        *
+        * @param {{key: string, type: string}} fieldTypes
+        * @param {Object} definition
+        */
+       function validateFieldTypes( fieldTypes, definition ) {
+               var field, value, requiredType;
+
+               for( field in definition ) {
+                       value = fieldTypes[ field ];
+                       requiredType = definition[ field ];
+
+                       if( !requiredType ) {
+                               throw new Error( 'Unknown field "' + field + '" 
found in structure' );
+                       }
+                       if( value !== undefined && typeof value !== 
requiredType ) {
+                               throw new Error( 'Field "' + field + '" has to 
be of type ' + requiredType );
+                       }
+               }
+       }
+
+}( time.Time ) );
diff --git a/DataValues/resources/time.js/tests/time.Time.validate.tests.js 
b/DataValues/resources/time.js/tests/time.Time.validate.tests.js
new file mode 100644
index 0000000..97c5240
--- /dev/null
+++ b/DataValues/resources/time.js/tests/time.Time.validate.tests.js
@@ -0,0 +1,152 @@
+/**
+ * @since 0.1
+ * @file
+ * @ingroup Time.js
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Werner
+ */
+( function( QUnit, $, Time ) {
+       'use strict';
+
+       var PRECISION = Time.PRECISION,
+               G = Time.CALENDAR.GREGORIAN,
+               J = Time.CALENDAR.JULIAN;
+
+       QUnit.module( 'time.js: time.Time.validate()' );
+
+       var validDefinitions = [
+               {
+                       calendarname: G,
+                       year: -44,
+                       precision: PRECISION.YEAR
+               }, {
+                       calendarname: J,
+                       year: 1492,
+                       month: 10,
+                       day: 12,
+                       precision: PRECISION.DAY
+               }, {
+                       calendarname: G,
+                       month: 3,
+                       year: -44,
+                       precision: PRECISION.MONTH
+               }, {
+                       calendarname: J,
+                       year: 1616,
+                       month: 4,
+                       day: 23,
+                       precision: PRECISION.DAY
+               }, {
+                       calendarname: G,
+                       year: 1616,
+                       month: 4,
+                       day: 22,
+                       precision: PRECISION.DAY
+               }, {
+                       calendarname: G,
+                       year: 2001,
+                       month: 1,
+                       day: 1,
+                       precision: PRECISION.DAY
+               }, {
+                       calendarname: G,
+                       year: 1989,
+                       month: 11,
+                       day: 20,
+                       precision: PRECISION.DAY
+               }
+       ];
+
+       QUnit.test( 'validating valid time definitions', function( assert ) {
+               $.each( validDefinitions, function( i, timeDefinition ) {
+                       var valid = true;
+                       try {
+                               Time.validate( timeDefinition ); // throws an 
error if failure
+                       } catch( e ) {
+                               valid = false;
+                       }
+
+                       assert.ok(
+                               valid,
+                               'valid definition ' + i + ' has been accepted 
by validate()'
+                       );
+               } );
+       } );
+
+       var validDefinition = {
+               calendarname: J,
+               year: 1492,
+               month: 10,
+               day: 12,
+               precision: PRECISION.DAY
+       };
+
+       function newInvalidTestDefinition( reason, change ) {
+               return {
+                       reason: reason,
+                       definition: $.extend( {}, validDefinition, change )
+               };
+       }
+
+       var invalidDefinitions = [
+               {
+                       reason: 'no object given',
+                       definition: null
+               },
+               newInvalidTestDefinition(
+                       'invalid precision (string)',
+                       { precision: 'foo' }
+               ),
+               newInvalidTestDefinition(
+                       'invalid numeric precision',
+                       { precision: Time.maxPrecision() + 1 }
+               ),
+               newInvalidTestDefinition(
+                       'invalid year (string)',
+                       { year: 'foo' }
+               ),
+               newInvalidTestDefinition(
+                       'invalid year NaN',
+                       { year: Number.NaN }
+               ),
+               newInvalidTestDefinition(
+                       'month above 12',
+                       { month: 13 }
+               ),
+               newInvalidTestDefinition(
+                       'month below 1',
+                       { month: -1 }
+               ),
+               newInvalidTestDefinition(
+                       'month below 1',
+                       { month: 0 }
+               ),
+               newInvalidTestDefinition(
+                       'day below 1',
+                       { month: 0 }
+               ),
+               newInvalidTestDefinition(
+                       'unknown calendar name',
+                       { calendarname: 'foo' }
+               )
+       ];
+
+       QUnit.test( 'validating invalid time definitions', function( assert ) {
+               Time.validate( newInvalidTestDefinition( '', { year: 1234 } 
).definition );
+               assert.ok(
+                       true,
+                       'Checked for test helper. Valid definition used as base 
is actually valid.'
+               );
+
+               $.each( invalidDefinitions, function( i, timeTestDefinition ) {
+                       assert.throws(
+                               function() {
+                                       Time.validate( 
timeTestDefinition.definition );
+                               },
+                               'Validation of time object ' + i + ' failed 
because of ' + timeTestDefinition.reason
+                       );
+               } );
+       } );
+
+}( QUnit, jQuery, time.Time ) );

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I1431c9f9bdeff711713a4f5c56ae8b1c63bcb533
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Daniel Werner <daniel.wer...@wikimedia.de>
Gerrit-Reviewer: Henning Snater <henning.sna...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to