Henning Snater has submitted this change and it was merged.

Change subject: Added tests for jQuery.valueview.ExpertFactory
......................................................................


Added tests for jQuery.valueview.ExpertFactory

Change-Id: I7fe43276d789f746f0c19c7dd89eb851d2460a66
---
M ValueView/ValueView.resources.php
M ValueView/ValueView.tests.qunit.php
M ValueView/resources/jquery.valueview/valueview.ExpertFactory.js
A ValueView/resources/jquery.valueview/valueview.experts/experts.Mock.js
M ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
A ValueView/tests/qunit/jquery.valueview/valueview.ExpertFactory.tests.js
6 files changed, 328 insertions(+), 11 deletions(-)

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



diff --git a/ValueView/ValueView.resources.php 
b/ValueView/ValueView.resources.php
index afab9e2..e2a73f0 100644
--- a/ValueView/ValueView.resources.php
+++ b/ValueView/ValueView.resources.php
@@ -145,6 +145,15 @@
                        )
                ),
 
+               'jquery.valueview.experts.mock' => $moduleTemplate + array( // 
mock expert for tests
+                       'scripts' => array(
+                               
'jquery.valueview/valueview.experts/experts.Mock.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.valueview.experts',
+                       ),
+               ),
+
                'jquery.valueview.experts.staticdom' => $moduleTemplate + array(
                        'scripts' => array(
                                
'jquery.valueview/valueview.experts/experts.StaticDom.js',
diff --git a/ValueView/ValueView.tests.qunit.php 
b/ValueView/ValueView.tests.qunit.php
index ffdaa94..c0bc370 100644
--- a/ValueView/ValueView.tests.qunit.php
+++ b/ValueView/ValueView.tests.qunit.php
@@ -61,6 +61,17 @@
                                'jquery.ui.suggester',
                        ),
                ),
+
+               'jquery.valueview.ExpertFactory.tests' => array(
+                       'scripts' => array(
+                               
"$bp/jquery.valueview/valueview.ExpertFactory.tests.js",
+                       ),
+                       'dependencies' => array(
+                               'jquery.valueview.experts', // contains 
ExpertFactory
+                               'jquery.valueview.experts.mock',
+                               'qunit.parameterize'
+                       ),
+               )
        );
 
 } );
diff --git a/ValueView/resources/jquery.valueview/valueview.ExpertFactory.js 
b/ValueView/resources/jquery.valueview/valueview.ExpertFactory.js
index 0f29bd3..5dd3131 100644
--- a/ValueView/resources/jquery.valueview/valueview.ExpertFactory.js
+++ b/ValueView/resources/jquery.valueview/valueview.ExpertFactory.js
@@ -4,7 +4,7 @@
  * @licence GNU GPL v2+
  * @author Daniel Werner < daniel.wer...@wikimedia.de >
  */
-( function( dv, dt, $, vv ) {
+( function( DataValue, dt, $, vv ) {
        'use strict';
 
        var SELF = vv.ExpertFactory = function ValueviewExpertFactory() {
@@ -32,7 +32,8 @@
                 * Registers a valueview expert for displaying values suitable 
for a certain data type or
                 * of a certain data value type.
                 *
-                * @param {dataTypes.DataType|dataValues.DataValue|Function} 
expertPurpose
+                * @param {dataTypes.DataType|Function} expertPurpose Can be 
either a DataType instance or a
+                *        DataValue constructor.
                 * @param {Function} expert Constructor of the expert
                 */
                registerExpert: function( expertPurpose, expert ) {
@@ -41,7 +42,7 @@
                        }
                        else if (
                                $.isFunction( expertPurpose ) // DataValue 
constructor
-                               && expertPurpose.prototype instanceof 
dv.DataValue
+                               && expertPurpose.prototype instanceof DataValue
                                && expertPurpose.TYPE
                        ) {
                                this.registerDataValueExpert( 
expertPurpose.TYPE, expert );
@@ -56,7 +57,7 @@
                 *
                 * @since 0.1
                 *
-                * @param {string} dataValueType
+                * @param {Function|string} dataValueType Either a DataValue 
constructor or its type.
                 * @param {Function} expert Constructor of the expert
                 */
                registerDataValueExpert: function( dataValueType, expert ) {
@@ -123,11 +124,13 @@
                 * @return string[]
                 */
                getCoveredDataTypes: function() {
-                       var types = [];
+                       var types = [],
+                               dataTypeExperts = this._expertsForDataTypes,
+                               dataValueExperts = 
this._expertsForDataValueTypes;
 
                        $.each( dt.getDataTypeIds(), function( i, dtType ) {
-                               if( this._expertsForDataTypes.hasOwnProperty( 
dtType )
-                                       || 
this._expertsForDataValueTypes.hasOwnProperty(
+                               if( dataTypeExperts.hasOwnProperty( dtType )
+                                       || dataValueExperts.hasOwnProperty(
                                                        dt.getDataType( dtType 
).getDataValueType()
                                                )
                                ) {
@@ -163,7 +166,7 @@
                                dataTypeId,
                                expert;
 
-                       if( onTheBasisOf instanceof dv.DataValue ) {
+                       if( onTheBasisOf instanceof DataValue ) {
                                valueType = onTheBasisOf.getType();
                        }
                        else if( onTheBasisOf instanceof dt.DataType ) {
@@ -172,7 +175,7 @@
                        }
                        else if (
                                $.isFunction( onTheBasisOf ) // DataValue 
constructor
-                               && onTheBasisOf.prototype instanceof 
dv.DataValue
+                               && onTheBasisOf.prototype instanceof DataValue
                                && onTheBasisOf.TYPE
                        ) {
                                valueType = onTheBasisOf.TYPE;
@@ -211,4 +214,4 @@
                }
        };
 
-}( dataValues, dataTypes, jQuery, jQuery.valueview ) );
+}( dataValues.DataValue, dataTypes, jQuery, jQuery.valueview ) );
diff --git 
a/ValueView/resources/jquery.valueview/valueview.experts/experts.Mock.js 
b/ValueView/resources/jquery.valueview/valueview.experts/experts.Mock.js
new file mode 100644
index 0000000..0bd584b
--- /dev/null
+++ b/ValueView/resources/jquery.valueview/valueview.experts/experts.Mock.js
@@ -0,0 +1,58 @@
+/**
+ * @file
+ * @ingroup ValueView
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < daniel.wer...@wikimedia.de >
+ */
+( function( $, vv ) {
+       'use strict';
+
+       var PARENT = vv.Expert;
+
+       /**
+        * Valueview expert for tests. Simply overwrites all abstract functions 
with some mock
+        * functions. A raw value can be set, all values are accepted.
+        *
+        * @since 0.1
+        *
+        * @constructor
+        * @extends jQuery.valueview.Expert
+        */
+       vv.experts.Mock = vv.expert( 'mock', PARENT, {
+               /**
+                * Current value.
+                * @type {*}
+                */
+               value: null,
+
+               /**
+                * @see jQuery.valueview.Expert.destroy
+                */
+               destroy: function() {
+                       this._value = null;
+                       PARENT.prototype.destroy.call( this );
+               },
+
+               /**
+                * @see jQuery.valueview.Expert._getRawValue
+                */
+               _getRawValue: function() {
+                       return this._value;
+               },
+
+               /**
+                * @see jQuery.valueview.Expert._setRawValue
+                */
+               _setRawValue: function( rawValue ) {
+                       this._value = rawValue;
+               },
+
+               /**
+                * @see jQuery.valueview.Expert.draw
+                */
+               draw: function() {
+                       this.$viewPort.empty();
+               }
+       } );
+
+}( jQuery, jQuery.valueview ) );
diff --git 
a/ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js 
b/ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
index 14e6399..53b3e03 100644
--- 
a/ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
+++ 
b/ValueView/resources/jquery.valueview/valueview.experts/experts.StaticDom.js
@@ -5,7 +5,7 @@
  * @author Daniel Werner < daniel.wer...@wikimedia.de >
  */
 ( function( $, vv ) {
-       'use strict'
+       'use strict';
 
        var PARENT = vv.Expert;
 
diff --git 
a/ValueView/tests/qunit/jquery.valueview/valueview.ExpertFactory.tests.js 
b/ValueView/tests/qunit/jquery.valueview/valueview.ExpertFactory.tests.js
new file mode 100644
index 0000000..ffde0c6
--- /dev/null
+++ b/ValueView/tests/qunit/jquery.valueview/valueview.ExpertFactory.tests.js
@@ -0,0 +1,236 @@
+/**
+ * @since 0.1
+ * @ingroup ValueView
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < daniel.wer...@wikimedia.de >
+ */
+
+( function( $, QUnit, dataValues, dataTypes ) {
+       'use strict';
+
+       var dv = dataValues,
+               dt = dataTypes,
+               vv = $.valueview,
+               ExpertFactory = vv.ExpertFactory,
+               MockExpertBase = vv.experts.Mock;
+
+       /**
+        * Returns a descriptive string about a valid expert base object (a 
DataType object, a
+        * DataValue object or a DataValue constructor).
+        *
+        * @param {dataTypes.DataType|dataValues.DataValue|Function} expertBasis
+        * @returns {string}
+        */
+       function expertBasisInfo( expertBasis ) {
+               if( expertBasis instanceof dt.DataType ) {
+                       return 'DataType with data value type "' + 
expertBasis.getDataValueType() + '"';
+               }
+               if( expertBasis instanceof dv.DataValue ) {
+                       return 'DataValue instance of type "' + 
expertBasis.getType() + '"';
+               }
+               // DataValue constructor:
+               return 'constructor for DataValue of type "' + expertBasis.TYPE 
+ '"';
+       }
+
+       /**
+        * Creates a new valueview expert constructor.
+        *
+        * @param {string} mockExpertId Used in the constructor name for simple 
identification if some
+        *        assertion goes wrong.
+        * @returns {jQuery.valueview.Expert}
+        */
+       function newMockExpertConstructor( mockExpertId ) {
+               return vv.expert(
+                       'mockexpert' + mockExpertId, // name
+                       MockExpertBase, // base
+                       {} // definition
+               );
+       }
+
+       var StringValue = dv.StringValue,
+               BoolValue = dv.BoolValue,
+               stringDataType = new dt.DataType( 'somestringtype', StringValue 
),
+               numberDataType = new dt.DataType( 'somenumbertype', 
dv.NumberValue ),
+               MockExpertForStringValue = newMockExpertConstructor( 
'ForStringValue' ),
+               MockExpertForBoolValue = newMockExpertConstructor( 
'ForBoolValue' ),
+               MockExpertForStringDataType = newMockExpertConstructor( 
'ForStringDataType' );
+
+       QUnit.module( 'jquery.valueview.ExpertFactory' );
+
+       QUnit.test( 'constructor', function( assert ) {
+               var expertFactory = new ExpertFactory();
+
+               assert.ok(
+                       expertFactory instanceof ExpertFactory,
+                       'New ExpertFactory instance created'
+               );
+
+               assert.ok(
+                       expertFactory.getCoveredDataValueTypes().length === 0,
+                       'Initially, new ExpertFactory has registered no experts 
for any data value type'
+               );
+
+               assert.ok(
+                       expertFactory.getCoveredDataTypes().length === 0,
+                       'Initially, new ExpertFactory has registered no experts 
for any data type'
+               );
+       } );
+
+       QUnit.test( 'test getCoveredDataValueTypes', function( assert ) {
+               var expertFactory = new ExpertFactory();
+
+               // Register two experts for data values:
+               expertFactory.registerExpert( StringValue, 
MockExpertForStringValue );
+               expertFactory.registerExpert( BoolValue, MockExpertForBoolValue 
);
+
+               // Register one data type expert, shouldn't make any difference:
+               expertFactory.registerExpert( stringDataType, 
MockExpertForBoolValue );
+
+               assert.ok(
+                       expertFactory.hasExpertFor( BoolValue ),
+                       'Expert registered for another data value type'
+               );
+
+               var coveredDvTypes = expertFactory.getCoveredDataValueTypes();
+
+               assert.equal(
+                       coveredDvTypes.length,
+                       2,
+                       'There are experts registered for exactly two data 
value types'
+               );
+
+               assert.ok(
+                       $.inArray( StringValue.TYPE, coveredDvTypes ) !== -1
+                               && $.inArray( BoolValue.TYPE, coveredDvTypes ) 
!== -1,
+                       'Both registered data value types are returned by 
getCoveredDataValueTypes()'
+               );
+       } );
+
+       // tests for registration of experts:
+
+       /**
+        * Array of test definitions as provider for 
"expertFactoryRegistrationTest" plus one "descr"
+        * field for each test.
+        *
+        * @type {Object[]}
+        */
+       var expertFactoryRegistrationTestCases = [
+               {
+                       title: 'empty ExpertFactory',
+                       register: [],
+                       expect: [
+                               [ StringValue, null ],
+                               [ stringDataType, null ]
+                       ]
+               }, {
+                       title: 'ExpertFactory with expert for string value, 
expert also suitable for string type',
+                       register: [
+                               [ StringValue, MockExpertForStringValue ]
+                       ],
+                       expect: [
+                               [ StringValue, MockExpertForStringValue ],
+                               [ new StringValue( 'foo' ), 
MockExpertForStringValue ],
+                               [ stringDataType, MockExpertForStringValue ], 
// data type uses value type
+                               [ BoolValue, null ],
+                               [ new BoolValue( true ), null ],
+                               [ numberDataType, null ]
+                       ]
+               }, {
+                       title: 'ExpertFactory for string data type. String 
value can\'t use this potentially more specialized expert',
+                       register: [
+                               [ stringDataType, MockExpertForStringDataType ]
+                       ],
+                       expect: [
+                               [ StringValue, null ],
+                               [ new StringValue( 'foo' ), null ],
+                               [ stringDataType, MockExpertForStringDataType ]
+                       ]
+               }, {
+                       title: 'ExpertFactory with two experts: For data value 
and for data type using that data value type',
+                       register: [
+                               [ StringValue, MockExpertForStringValue ],
+                               [ stringDataType, MockExpertForStringDataType ]
+                       ],
+                       expect: [
+                               [ StringValue, MockExpertForStringValue ],
+                               [ stringDataType, MockExpertForStringDataType ],
+                               [ BoolValue, null ]
+                       ]
+               }, {
+                       title: 'ExpertFactory with two experts for two 
different data value types',
+                       register: [
+                               [ StringValue, MockExpertForStringValue ],
+                               [ BoolValue, MockExpertForBoolValue ]
+                       ],
+                       expect: [
+                               [ StringValue, MockExpertForStringValue ],
+                               [ BoolValue, MockExpertForBoolValue ],
+                               [ numberDataType, null ]
+                       ]
+               }
+       ];
+
+       /**
+        * Test for registration of experts to ExpertFactory and expected 
conditions afterwards.
+        *
+        * @param {QUnit.assert} assert
+        * @param {Array[]} toRegister Array containing arrays where each one 
tells a ExpertFactory what
+        *        experts to register. The inner array has to consist out of 
two objects as
+        *        ExpertFactory.registerExpert would take them.
+        * @param {Array[]} toExpect Array containing arrays where each one 
states one expected
+        *        condition of the ExpertFactory after registration of what is 
given in the first
+        *        parameter. Each inner array should contain a data type, data 
value or data value
+        *        constructor and an expert which is expected to be registered 
for it.
+        */
+       function expertFactoryRegistrationTest( assert, toRegister, toExpect  ) 
{
+               var expertFactory = new ExpertFactory();
+
+               assert.ok(
+                       expertFactory instanceof ExpertFactory,
+                       'New expert factory created'
+               );
+
+               // register experts as per definition:
+               $.each( toRegister, function( i, registerPair ) {
+                       var expertBasis = registerPair[0],
+                               expert = registerPair[1];
+
+                       expertFactory.registerExpert( expertBasis, expert );
+
+                       assert.ok(
+                               true,
+                               'Expert registered for ' + expertBasisInfo( 
expertBasis )
+                       );
+               } );
+
+               // check for expected conditions:
+               $.each( toExpect, function( i, expectPair ) {
+                       var expertBasis = expectPair[0],
+                               expectedExpert = expectPair[1],
+                               expertBasisInfoMsg = expertBasisInfo( 
expertBasis );
+
+                       assert.strictEqual(
+                               expertFactory.hasExpertFor( expertBasis ),
+                               expectedExpert !== null,
+                               'Expert factory has ' + ( expectedExpert !== 
null ? '' : ' no' )
+                                       + ' expert for' + expertBasisInfoMsg
+                       );
+
+                       assert.strictEqual(
+                               expertFactory.getExpert( expertBasis ),
+                               expectedExpert,
+                               'Requesting expert for ' + expertBasisInfoMsg +
+                                       ( expectedExpert !== null ? ' returns 
expected expert' : ' returns null' )
+                       );
+               } );
+       }
+
+       // Run defined tests on expertFactoryRegistrationTest:
+       QUnit
+       .cases( expertFactoryRegistrationTestCases )
+               .test( 'experts registration', function( params, assert ) {
+                       expertFactoryRegistrationTest( assert, params.register, 
params.expect );
+               } );
+
+}( jQuery, QUnit, dataValues, dataTypes ) );

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I7fe43276d789f746f0c19c7dd89eb851d2460a66
Gerrit-PatchSet: 4
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: Tobias Gritschacher <tobias.gritschac...@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