Daniel Werner has uploaded a new change for review. https://gerrit.wikimedia.org/r/50157
Change subject: dv.util.inherit has new parameter for defining a constructor's name ...................................................................... dv.util.inherit has new parameter for defining a constructor's name Change-Id: I78bbf26d8d241574773888a3aa28bc12d34f1b46 --- M DataValues/resources/dataValues.util.js M DataValues/tests/qunit/dataValues.util.inherit.tests.js 2 files changed, 45 insertions(+), 19 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DataValues refs/changes/57/50157/1 diff --git a/DataValues/resources/dataValues.util.js b/DataValues/resources/dataValues.util.js index 8788167..00bec95 100644 --- a/DataValues/resources/dataValues.util.js +++ b/DataValues/resources/dataValues.util.js @@ -2,7 +2,7 @@ * @file * @ingroup DataValues * @licence GNU GPL v2+ - * @author Daniel Werner + * @author Daniel Werner < [email protected] > */ ( function( $, dv ) { 'use strict'; @@ -18,16 +18,23 @@ * Helper for prototypical inheritance. * @since 0.1 * - * @param {Function} base Constructor which will be used for the prototype chain. + * @param {string} name (optional) The name of the new constructor. This is handy for debugging + * purposes since instances of the constructor might be displayed under that name. + * @param {Function} base Constructor which will be used for the prototype chain. This function + * will not be the constructor returned by the function but will be called by it. * @param {Function} [constructor] for overwriting base constructor. Can be omitted. * @param {Object} [members] properties overwriting or extending those of the base. * @return Function Constructor of the new, extended type. */ - dv.util.inherit = function( base, constructor, members ) { - // allow to omit constructor since it can be inherited directly. But if given, require it as - // second parameter for readability. If no constructor, second parameter is the prototype - // extension object. - if( members === undefined ) { + dv.util.inherit = function( name, base, constructor, members ) { + // the name is optional + if( typeof name !== 'string' ) { + members = constructor; constructor = base; base = name; name = false; + } + + // allow to omit constructor since it can be inherited directly. But if given, require it as second parameter + // for readability. If no constructor, second parameter is the prototype extension object. + if( !members ) { if( $.isFunction( constructor ) ) { members = {}; } else { @@ -35,7 +42,16 @@ constructor = false; } } - var NewConstructor = constructor || function() { base.apply( this, arguments ); }; + // if no name is given, find suitable constructor's name + name = name || constructor.name || ( base.name ? base.name + '_SubProto' : 'SomeInherited' ); + + // function we execute in our real constructor created by evil eval: + var evilsSeed = constructor || base, + NewConstructor; + + // for creating a named function with a variable name, there is just no other way... + eval( 'NewConstructor = function ' + name + + '(){ evilsSeed.apply( this, arguments ); }' ); var NewPrototype = function(){}; // new constructor for avoiding base constructor and with it any side-effects NewPrototype.prototype = base.prototype; diff --git a/DataValues/tests/qunit/dataValues.util.inherit.tests.js b/DataValues/tests/qunit/dataValues.util.inherit.tests.js index d09b35f..a94ca4f 100644 --- a/DataValues/tests/qunit/dataValues.util.inherit.tests.js +++ b/DataValues/tests/qunit/dataValues.util.inherit.tests.js @@ -8,7 +8,7 @@ * @licence GNU GPL v2+ * @author Daniel Werner */ -( function( dv, $, QUnit, undefined ) { +( function( dv, $, QUnit ) { 'use strict'; QUnit.module( 'dataValues.util.inherit', QUnit.newMwEnvironment() ); @@ -35,7 +35,13 @@ else if( constructor === null ) { // constructor omitted, check for right param mapping: C = dv.util.inherit( base, members ); - var C2 = dv.util.inherit( base, C.prototype.constructor, members ); + var C2 = dv.util.inherit( base, C.prototype.constructor, members ), + origConstructorOfC = C.prototype.constructor; + + // constructors will never be the same since a new function will be created in inherit(), + // so we have to set them to the same to test for all the other prototype members. + C.prototype.constructor = null; + C2.prototype.constructor = null; QUnit.assert.deepEqual( C.prototype, @@ -43,6 +49,7 @@ 'inherit() works as expected if "constructor" parameter was omitted.' ); C2 = null; + C.prototype.constructor = origConstructorOfC; } else if( members === null ) { C = dv.util.inherit( base, constructor ); @@ -60,14 +67,6 @@ ( new C() ) instanceof base && ( new C() ) instanceof C, '"instanceof" is working like it should' ); - - if( constructor !== null ) { - QUnit.assert.equal( - C, - constructor, - 'prototypes constructor property is set to given constructor' - ); - } var proto = $.extend( {}, C.prototype ); if( members === null || !members.hasOwnProperty( 'constructor' ) ) { @@ -89,7 +88,7 @@ foo: 'baa' }, - inheritConstructor = function() { + inheritConstructor = function InheritTestConstructor() { this.foo = 'test'; }, @@ -120,9 +119,20 @@ var C1 = inheritTest( Object, inheritConstructor, null ); inheritConstructorTest( C1 ); + QUnit.assert.equal( + C1.name, + inheritConstructor.name, + 'Constructor returned by inherit() takes name of given constructor function' + ); + // inherit from C2: var C2 = inheritTest( C1, null, inheritMembers ); inheritConstructorTest( C2 ); + + QUnit.assert.ok( + C2.name.indexOf( inheritConstructor.name ) === 0, + 'Constructor returned by inherit() uses name of given constructor plus suffix' + ); } ); QUnit.test( 'inherit( base, constructor, members )', function( assert ) { -- To view, visit https://gerrit.wikimedia.org/r/50157 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I78bbf26d8d241574773888a3aa28bc12d34f1b46 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DataValues Gerrit-Branch: master Gerrit-Owner: Daniel Werner <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
