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 < [email protected] >
+ */
+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 <[email protected]>
Gerrit-Reviewer: Henning Snater <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits