From: Krinkle Date: Sun, 29 May 2011 02:54:01 +0000 (+0000) Subject: Adding or adjusting front-end function and variable documentation per our conventions. X-Git-Tag: 1.31.0-rc.0~29877 X-Git-Url: https://git.cyclocoop.org/%28%28?a=commitdiff_plain;h=eb87e5c4a1a6ee759567bc498726bf2c5ab2c0e0;p=lhc%2Fweb%2Fwiklou.git Adding or adjusting front-end function and variable documentation per our conventions. Also did some trivial clean up, JSHint fixes and performance optimizations while at it. (per http://www.mediawiki.org/wiki/JavaScript_performance ) * Missing semicolons. * [mediawiki.js Line 540] Unreachable 'registry' after 'throw'. * [mediawiki.log.js] Checked for window.console but used console. * Added callback option to mw.util.toggleToc (forwarded to jQuery.fn.slideUp/Down) * Made mw.log argument more descriptive (logmsg instead of string) * Using deepEqual(, true) instead of ok() when asserting true. (ok() is like casting a boolean (or a plain if() statement) to verify that something is not falsy) Added missing test suites for: * mw.util.toggleToc (follow-up r88732, Dummy check was introduced in r87898) /me has been infected by Reedy and will be doing more of this tonight. --- diff --git a/resources/mediawiki.util/mediawiki.util.jpegmeta.js b/resources/mediawiki.util/mediawiki.util.jpegmeta.js index 08e0748384..5e5f338777 100644 --- a/resources/mediawiki.util/mediawiki.util.jpegmeta.js +++ b/resources/mediawiki.util/mediawiki.util.jpegmeta.js @@ -723,11 +723,11 @@ }; /* JsJpegMeta ends here */ - + mw.util = $.extend( mw.util || {}, { jpegmeta: function( fileReaderResult, fileName ) { return new JpegMeta.JpegFile( fileReaderResult, fileName ); } } ); - + } )( jQuery, mediaWiki ); \ No newline at end of file diff --git a/resources/mediawiki.util/mediawiki.util.js b/resources/mediawiki.util/mediawiki.util.js index ec5c3279a7..6f08fc02f2 100644 --- a/resources/mediawiki.util/mediawiki.util.js +++ b/resources/mediawiki.util/mediawiki.util.js @@ -6,6 +6,9 @@ mw.util = $.extend( mw.util || {}, { /* Initialisation */ + /** + * @var boolean Wether or not already initialised + */ 'initialised' : false, 'init' : function() { if ( this.initialised === false ) { @@ -93,9 +96,11 @@ // Only add it if there is a TOC and there is no toggle added already if ( $tocContainer.size() && $tocTitle.size() && !$tocToggleLink.size() ) { var hideTocCookie = $.cookie( 'mw_hidetoc' ); - $tocToggleLink = $( '' ).text( mw.msg( 'hidetoc' ) ).click( function(e){ - e.preventDefault(); - mw.util.toggleToc( $(this) ); + $tocToggleLink = $( '' ) + .text( mw.msg( 'hidetoc' ) ) + .click( function(e){ + e.preventDefault(); + mw.util.toggleToc( $(this) ); } ); $tocTitle.append( $tocToggleLink.wrap( '' ).parent().prepend( ' [' ).append( '] ' ) ); @@ -116,7 +121,7 @@ /** * Encode the string like PHP's rawurlencode * - * @param str String to be encoded + * @param str string String to be encoded */ 'rawurlencode' : function( str ) { str = ( str + '' ).toString(); @@ -130,7 +135,7 @@ * We want / and : to be included as literal characters in our title URLs * as they otherwise fatally break the title * - * @param str String to be encoded + * @param str string String to be encoded */ 'wikiUrlencode' : function( str ) { return this.rawurlencode( str ) @@ -140,7 +145,7 @@ /** * Get the link to a page name (relative to wgServer) * - * @param str Page name to get the link for. + * @param str string Page name to get the link for. * @return string Location for a page with name of 'str' or boolean false on error. */ 'wikiGetlink' : function( str ) { @@ -152,8 +157,8 @@ * Get address to a script in the wiki root. * For index.php use mw.config.get( 'wgScript' ) * - * @param str Name of script (eg. 'api'), defaults to 'index' - * @return str Address to script (eg. '/w/api.php' ) + * @param str string Name of script (eg. 'api'), defaults to 'index' + * @return string Address to script (eg. '/w/api.php' ) */ 'wikiScript' : function( str ) { return mw.config.get( 'wgScriptPath' ) + '/' + ( str || 'index' ) + mw.config.get( 'wgScriptExtension' ); @@ -162,8 +167,8 @@ /** * Append a new style block to the head * - * @param text String CSS to be appended - * @return CSSStyleSheet object + * @param text string CSS to be appended + * @return CSSStyleSheet */ 'addCSS' : function( text ) { var s = document.createElement( 'style' ); @@ -174,24 +179,27 @@ } else { s.appendChild( document.createTextNode( text + '' ) ); // Safari sometimes borks on null } - document.getElementsByTagName("head")[0].appendChild( s ); + document.getElementsByTagName('head')[0].appendChild( s ); return s.sheet || s; }, /** * Hide/show the table of contents element * - * @param $toggleLink jQuery object of the toggle link - * @return String boolean visibility of the toc (true means it's visible) + * @param $toggleLink jQuery A jQuery object of the toggle link. + * @param callback function Function to be called after the toggle is + * completed (including the animation) (optional) + * @return mixed Boolean visibility of the toc (true if it's visible) + * or Null if there was no table of contents. */ - 'toggleToc' : function( $toggleLink ) { + 'toggleToc' : function( $toggleLink, callback ) { var $tocList = $( '#toc ul:first' ); // This function shouldn't be called if there's no TOC, // but just in case... if ( $tocList.size() ) { if ( $tocList.is( ':hidden' ) ) { - $tocList.slideDown( 'fast' ); + $tocList.slideDown( 'fast', callback ); $toggleLink.text( mw.msg( 'hidetoc' ) ); $.cookie( 'mw_hidetoc', null, { expires: 30, @@ -199,7 +207,7 @@ } ); return true; } else { - $tocList.slideUp( 'fast' ); + $tocList.slideUp( 'fast', callback ); $toggleLink.text( mw.msg( 'showtoc' ) ); $.cookie( 'mw_hidetoc', '1', { expires: 30, @@ -208,7 +216,7 @@ return false; } } else { - return false; + return null; } }, @@ -216,8 +224,9 @@ * Grab the URL parameter value for the given parameter. * Returns null if not found. * - * @param param The parameter name - * @param url URL to search through (optional) + * @param param string The parameter name. + * @param url string URL to search through (optional) + * @return mixed Parameter value or null. */ 'getParamValue' : function( param, url ) { url = url ? url : document.location.href; @@ -230,12 +239,17 @@ return null; }, - // Access key prefix. - // Will be re-defined based on browser/operating system detection in - // mw.util.init(). + /** + * @var string + * Access key prefix. Will be re-defined based on browser/operating system + * detection in mw.util.init(). + */ 'tooltipAccessKeyPrefix' : 'alt-', - // Regex to match accesskey tooltips + /** + * @var RegExp + * Regex to match accesskey tooltips. + */ 'tooltipAccessKeyRegexp': /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/, /** @@ -244,7 +258,7 @@ * otherwise, all the nodes that will probably have accesskeys by * default are updated. * - * @param nodeList jQuery object, or array of elements + * @param nodeList mixed A jQuery object, or array of elements to update. */ 'updateTooltipAccessKeys' : function( nodeList ) { var $nodes; @@ -274,8 +288,11 @@ } ); }, - // jQuery object that refers to the page-content element - // Populated by init() + /* + * @var jQuery + * A jQuery object that refers to the page-content element + * Populated by init(). + */ '$content' : null, /** @@ -284,8 +301,8 @@ * p-cactions (Content actions), p-personal (Personal tools), * p-navigation (Navigation), p-tb (Toolbox) * - * The first three paramters are required, others are optionals. Though - * providing an id and tooltip is recommended. + * The first three paramters are required, the others are optional and + * may be null. Though providing an id and tooltip is recommended. * * By default the new link will be added to the end of the list. To * add the link before a given existing item, pass the DOM node @@ -297,21 +314,21 @@ * 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', '#t-print' * ) * - * @param portlet ID of the target portlet ( 'p-cactions' or 'p-personal' etc.) - * @param href Link URL - * @param text Link text - * @param id ID of the new item, should be unique and preferably have - * the appropriate prefix ( 'ca-', 'pt-', 'n-' or 't-' ) - * @param tooltip Text to show when hovering over the link, without accesskey suffix - * @param accesskey Access key to activate this link (one character, try - * to avoid conflicts. Use $( '[accesskey=x]' ).get() in the console to - * see if 'x' is already used. - * @param nextnode DOM node or jQuery-selector string of the item that the new - * item should be added before, should be another item in the same - * list, it will be ignored otherwise + * @param portlet string ID of the target portlet ( 'p-cactions' or 'p-personal' etc.) + * @param href string Link URL + * @param text string Link text + * @param id string ID of the new item, should be unique and preferably have + * the appropriate prefix ( 'ca-', 'pt-', 'n-' or 't-' ) + * @param tooltip string Text to show when hovering over the link, without accesskey suffix + * @param accesskey string Access key to activate this link (one character, try + * to avoid conflicts. Use $( '[accesskey=x]' ).get() in the console to + * see if 'x' is already used. + * @param nextnode mixed DOM Node or jQuery-selector string of the item that the new + * item should be added before, should be another item in the same + * list, it will be ignored otherwise * - * @return The DOM node of the new item (a LI element, or A element for - * older skins) or null. + * @return mixed The DOM Node of the added item (a ListItem or Anchor element, + * depending on the skin) or null if no element was added to the document. */ 'addPortletLink' : function( portlet, href, text, id, tooltip, accesskey, nextnode ) { @@ -399,7 +416,7 @@ } else { $ul.append( $item ); } - + return $item[0]; } @@ -412,8 +429,8 @@ * * @param message mixed The DOM-element or HTML-string to be put inside the message box. * @param className string Used in adding a class; should be different for each call - * to allow CSS/JS to hide different boxes. null = no class used. - * @return boolean True on success, false on failure + * to allow CSS/JS to hide different boxes. null = no class used. + * @return boolean True on success, false on failure. */ 'jsMessage' : function( message, className ) { @@ -457,7 +474,11 @@ * according to HTML5 specification. Please note the specification * does not validate a domain with one character. * - * FIXME: should be moved to or replaced by a JavaScript validation module. + * @todo FIXME: should be moved to or replaced by a JavaScript validation module. + * + * @param mailtxt string E-mail address to be validated. + * @return mixed Null if mailtxt was an empty string, otherwise true/false + * is determined by validation. */ 'validateEmail' : function( mailtxt ) { if( mailtxt === '' ) { @@ -525,14 +546,27 @@ ); return (null !== mailtxt.match( HTML5_email_regexp ) ); }, - // Note: borrows from IP::isIPv4 + + /** + * Note: borrows from IP::isIPv4 + * + * @param address string + * @param allowBlock boolean + * @return boolean + */ 'isIPv4Address' : function( address, allowBlock ) { var block = allowBlock ? '(?:\\/(?:3[0-2]|[12]?\\d))?' : ''; var RE_IP_BYTE = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])'; var RE_IP_ADD = '(?:' + RE_IP_BYTE + '\\.){3}' + RE_IP_BYTE; return address.search( new RegExp( '^' + RE_IP_ADD + block + '$' ) ) != -1; }, - // Note: borrows from IP::isIPv6 + /** + * Note: borrows from IP::isIPv6 + * + * @param address string + * @param allowBlock boolean + * @return boolean + */ 'isIPv6Address' : function( address, allowBlock ) { var block = allowBlock ? '(?:\\/(?:12[0-8]|1[01][0-9]|[1-9]?\\d))?' : ''; var RE_IPV6_ADD = diff --git a/resources/mediawiki/mediawiki.htmlform.js b/resources/mediawiki/mediawiki.htmlform.js index 0b8cf835a6..1a6acd6f1d 100644 --- a/resources/mediawiki/mediawiki.htmlform.js +++ b/resources/mediawiki/mediawiki.htmlform.js @@ -3,15 +3,27 @@ */ ( function( $ ) { -// Fade or snap depending on argument +/** + * jQuery plugin to fade or snap to visible state. + * + * @param boolean instantToggle (optional) + * @return jQuery + */ $.fn.goIn = function( instantToggle ) { - if ( typeof instantToggle != 'undefined' && instantToggle === true ) { + if ( instantToggle !== undefined && instantToggle === true ) { return $(this).show(); } return $(this).stop( true, true ).fadeIn(); }; + +/** + * jQuery plugin to fade or snap to hiding state. + * + * @param boolean instantToggle (optional) + * @return jQuery + */ $.fn.goOut = function( instantToggle ) { - if ( typeof instantToggle != 'undefined' && instantToggle === true ) { + if ( instantToggle !== undefined && instantToggle === true ) { return $(this).hide(); } return $(this).stop( true, true ).fadeOut(); @@ -34,12 +46,12 @@ $.fn.liveAndTestAtStart = function( callback ){ // Document ready: $( function() { - // animate the SelectOrOther fields, to only show the text field when - // 'other' is selected + // Animate the SelectOrOther fields, to only show the text field when + // 'other' is selected. $( '.mw-htmlform-select-or-other' ).liveAndTestAtStart( function( instant ) { var $other = $( '#' + $(this).attr( 'id' ) + '-other' ); $other = $other.add( $other.siblings( 'br' ) ); - if ( $(this).val() == 'other' ) { + if ( $(this).val() === 'other' ) { $other.goIn( instant ); } else { $other.goOut( instant ); @@ -49,4 +61,4 @@ $( function() { }); -})( jQuery ); \ No newline at end of file +})( jQuery ); diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js index f36d21cbd9..9bf9506f40 100644 --- a/resources/mediawiki/mediawiki.js +++ b/resources/mediawiki/mediawiki.js @@ -210,7 +210,7 @@ window.mediaWiki = new ( function( $ ) { /* * Dummy function which in debug mode can be replaced with a function that - * emulates console.log in console-less environments. + * emulates console.log in console-less environments. */ this.log = function() { }; @@ -318,7 +318,8 @@ window.mediaWiki = new ( function( $ ) { return $marker; } mw.log( 'getMarker> No found, inserting dynamically.' ); - return $marker = $( '' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' ); + $marker = $( '' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' ); + return $marker; } } @@ -512,7 +513,7 @@ window.mediaWiki = new ( function( $ ) { }; if ( $.isArray( script ) ) { var done = 0; - if (script.length == 0 ) { + if ( script.length === 0 ) { // No scripts in this module? Let's dive out early. markModuleReady(); } @@ -534,8 +535,8 @@ window.mediaWiki = new ( function( $ ) { if ( window.console && typeof window.console.log === 'function' ) { console.log( _fn + 'Exception thrown by ' + module + ': ' + e.message ); } - throw e; registry[module].state = 'error'; + throw e; } } @@ -674,8 +675,8 @@ window.mediaWiki = new ( function( $ ) { !done && ( !this.readyState - || this.readyState === "loaded" - || this.readyState === "complete" + || this.readyState === 'loaded' + || this.readyState === 'complete' ) ) { done = true; @@ -1031,7 +1032,7 @@ window.mediaWiki = new ( function( $ ) { */ this.version = function() { return mediaWiki.loader.getVersion.apply( mediaWiki.loader, arguments ); - } + }; /** * Gets the state of a module @@ -1120,7 +1121,7 @@ window.mediaWiki = new ( function( $ ) { } // Regular open tag s += '>'; - if ( typeof contents === 'string') { + if ( typeof contents === 'string' ) { // Escaped s += this.escape( contents ); } else if ( contents instanceof this.Raw ) { diff --git a/resources/mediawiki/mediawiki.log.js b/resources/mediawiki/mediawiki.log.js index c0f8738034..46fd98eddc 100644 --- a/resources/mediawiki/mediawiki.log.js +++ b/resources/mediawiki/mediawiki.log.js @@ -13,16 +13,16 @@ * * @author Michael Dale * @author Trevor Parscal - * @param {string} string Message to output to console + * @param logmsg string Message to output to console. */ - mw.log = function( string ) { + mw.log = function( msg ) { // Allow log messages to use a configured prefix to identify the source window (ie. frame) if ( mw.config.exists( 'mw.log.prefix' ) ) { - string = mw.config.get( 'mw.log.prefix' ) + '> ' + string; + logmsg = mw.config.get( 'mw.log.prefix' ) + '> ' + logmsg; } // Try to use an existing console - if ( typeof window.console !== 'undefined' && typeof window.console.log == 'function' ) { - console.log( string ); + if ( window.console !== undefined && $.isFunction( window.console.log ) ) { + window.console.log( logmsg ); } else { // Set timestamp var d = new Date(); @@ -58,7 +58,7 @@ 'white-space': 'pre-wrap', 'padding': '0.125em 0.25em' } ) - .text( string ) + .text( logmsg ) .prepend( '[' + time + ']' ) ); } diff --git a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js b/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js index e0d5b98f63..6be5212e18 100644 --- a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js +++ b/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js @@ -1,7 +1,7 @@ module( 'jquery.autoEllipsis.js' ); test( '-- Initial check', function(){ - + expect(1); ok( jQuery.fn.autoEllipsis, 'jQuery.fn.autoEllipsis defined' ); }); @@ -21,6 +21,8 @@ function findDivergenceIndex( a, b ) { } test( 'Position right', function() { + expect(3); + // We need this thing to be visible, so append it to the DOM var origText = 'This is a really long random string and there is no way it fits in 100 pixels.'; var $wrapper = createWrappedDiv( origText ); @@ -33,7 +35,7 @@ test( 'Position right', function() { // Check that the text fits by turning on word wrapping $span.css( 'whiteSpace', 'nowrap' ); - ok( $span.width() <= $span.parent().width(), "Text fits (span's width is no larger than its parent's width)" ); + deepEqual( $span.width() <= $span.parent().width(), true, "Text fits (span's width is no larger than its parent's width)" ); // Add one character using scary black magic var spanText = $span.text(); @@ -42,7 +44,7 @@ test( 'Position right', function() { // Put this text in the span and verify it doesn't fit $span.text( spanText ); - ok( $span.width() > $span.parent().width(), 'Fit is maximal (adding one character makes it not fit any more)' ); + deepEqual( $span.width() > $span.parent().width(), true, 'Fit is maximal (adding one character makes it not fit any more)' ); // Clean up $wrapper.remove(); diff --git a/tests/qunit/suites/resources/jquery/jquery.colorUtil.js b/tests/qunit/suites/resources/jquery/jquery.colorUtil.js index 5c8f0676f4..9ac289d3ae 100644 --- a/tests/qunit/suites/resources/jquery/jquery.colorUtil.js +++ b/tests/qunit/suites/resources/jquery/jquery.colorUtil.js @@ -1,11 +1,12 @@ module( 'jquery.colorUtil.js' ); test( '-- Initial check', function(){ - + expect(1); ok( jQuery.colorUtil, 'jQuery.colorUtil defined' ); }); test( 'getRGB', function(){ + expect(18); equal( typeof jQuery.colorUtil.getRGB(), 'undefined', 'No arguments' ); equal( typeof jQuery.colorUtil.getRGB( '' ), 'undefined', 'Empty string' ); @@ -32,6 +33,8 @@ test( 'getRGB', function(){ }); test( 'rgbToHsl', function(){ + expect(4); + var hsl = jQuery.colorUtil.rgbToHsl( 144, 238, 144 ); var dualDecimals = function(a,b){ return Math.round(a*100)/100; @@ -45,6 +48,8 @@ test( 'rgbToHsl', function(){ }); test( 'hslToRgb', function(){ + expect(4); + var rgb = jQuery.colorUtil.hslToRgb( 0.3, 0.7, 0.8 ); ok( rgb, 'Basic return evaluation' ); @@ -55,6 +60,7 @@ test( 'hslToRgb', function(){ }); test( 'getColorBrightness', function(){ + expect(2); var a = jQuery.colorUtil.getColorBrightness( 'red', +0.1 ); diff --git a/tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js b/tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js index b53e062d76..6fd681fc4c 100644 --- a/tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js +++ b/tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js @@ -54,5 +54,5 @@ test( 'Comparison functions', function(){ ok( $j.compareObject( { foo: 1 }, { foo: 1 } ), 'compareObject: Two the same objects' ); ok( !$j.compareObject( { bar: true }, { baz: false } ), 'compareObject: Two different objects (false)' ); - + }); \ No newline at end of file diff --git a/tests/qunit/suites/resources/jquery/jquery.tabIndex.js b/tests/qunit/suites/resources/jquery/jquery.tabIndex.js index 73a180062b..b320d63817 100644 --- a/tests/qunit/suites/resources/jquery/jquery.tabIndex.js +++ b/tests/qunit/suites/resources/jquery/jquery.tabIndex.js @@ -1,6 +1,7 @@ module( 'jquery.tabIndex.js' ); test( '-- Initial check', function(){ + expect(2); ok( $.fn.firstTabIndex, '$.fn.firstTabIndex defined' ); ok( $.fn.lastTabIndex, '$.fn.lastTabIndex defined' ); @@ -8,14 +9,15 @@ test( '-- Initial check', function(){ }); test( 'firstTabIndex', function(){ + expect(2); var testEnvironment = -'
\ - \ - \ - \ - \ -
'; +'
' + + '' + + '' + + '' + + '' + +'
'; var $testA = $( '
' ).html( testEnvironment ).appendTo( 'body' ); deepEqual( $testA.firstTabIndex(), 2, 'First tabindex should be 2 within this context.' ); @@ -29,14 +31,15 @@ test( 'firstTabIndex', function(){ }); test( 'lastTabIndex', function(){ + expect(2); var testEnvironment = -'
\ - \ - \ - \ - \ -
'; +'
' + + '' + + '' + + '' + + '' + +'
'; var $testA = $( '
' ).html( testEnvironment ).appendTo( 'body' ); deepEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' ); diff --git a/tests/qunit/suites/resources/mediawiki.util/mediawiki.util.js b/tests/qunit/suites/resources/mediawiki.util/mediawiki.util.js index cfedac9720..68ce17c161 100644 --- a/tests/qunit/suites/resources/mediawiki.util/mediawiki.util.js +++ b/tests/qunit/suites/resources/mediawiki.util/mediawiki.util.js @@ -34,6 +34,7 @@ test( 'wikiGetlink', function(){ }); test( 'wikiScript', function(){ + expect(2); mw.config.set({ 'wgScript': '/w/index.php', @@ -41,28 +42,58 @@ test( 'wikiScript', function(){ 'wgScriptExtension': '.php' }); - equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ), 'Defaults to index.php and is equal to wgScript.' ); + equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ), 'Defaults to index.php and is equal to wgScript' ); + deepEqual( mw.util.wikiScript( 'api' ), '/w/api.php' ); }); test( 'addCSS', function(){ + expect(3); - var a = mw.util.addCSS( '#bodyContent { visibility: hidden; }' ); + window.a = mw.util.addCSS( '#bodyContent { visibility: hidden; }' ); ok( a, 'function works' ); deepEqual( a.disabled, false, 'property "disabled" is available and set to false' ); var $b = $('#bodyContent'); - equal( $b.css('visibility'), 'hidden', 'Added style properties are in effect.' ); - + equal( $b.css('visibility'), 'hidden', 'Added style properties are in effect' ); }); -/** - * @fixme this seems to only test for the existence of the function, and does not confirm that it works - */ test( 'toggleToc', function(){ + expect(3); + + deepEqual( mw.util.toggleToc(), null, 'Return null if there is no table of contents on the page.' ); + + var tocHtml = + '
' + + '
' + + '

Contents

' + + ' [Hide ]' + + '
' + + '
' + + '
'; + var $toc = $(tocHtml).appendTo( 'body' ); + var $toggleLink = $( '#togglelink' ); + + // Toggle animation is asynchronous + // QUnit should not finish this test() untill they are all done + stop(); + + var actionC = function(){ + start(); + + // Clean up + $toc.remove(); + }; + var actionB = function(){ + deepEqual( mw.util.toggleToc( $toggleLink, actionC ), true, 'Return boolean true if the TOC is now visible.' ); + }; + var actionA = function(){ + deepEqual( mw.util.toggleToc( $toggleLink, actionB ), false, 'Return boolean false if the TOC is now hidden.' ); + }; + + actionA(); - ok( mw.util.toggleToc ); }); @@ -126,21 +157,23 @@ test( 'jsMessage', function(){ }); test( 'validateEmail', function(){ + expect(6); - deepEqual( mw.util.validateEmail( "" ), null, 'Empty string should return null' ); - deepEqual( mw.util.validateEmail( "user@localhost" ), true ); + deepEqual( mw.util.validateEmail( "" ), null, 'Should return null for empty string ' ); + deepEqual( mw.util.validateEmail( "user@localhost" ), true, 'Return true for a valid e-mail address' ); // testEmailWithCommasAreInvalids - deepEqual( mw.util.validateEmail( "user,foo@example.org" ), false, 'Comma' ); - deepEqual( mw.util.validateEmail( "userfoo@ex,ample.org" ), false, 'Comma' ); + deepEqual( mw.util.validateEmail( "user,foo@example.org" ), false, 'Emails with commas are invalid' ); + deepEqual( mw.util.validateEmail( "userfoo@ex,ample.org" ), false, 'Emails with commas are invalid' ); // testEmailWithHyphens - deepEqual( mw.util.validateEmail( "user-foo@example.org" ), true, 'Hyphen' ); - deepEqual( mw.util.validateEmail( "userfoo@ex-ample.org" ), true, 'Hyphen' ); + deepEqual( mw.util.validateEmail( "user-foo@example.org" ), true, 'Emails may contain a hyphen' ); + deepEqual( mw.util.validateEmail( "userfoo@ex-ample.org" ), true, 'Emails may contain a hyphen' ); }); test( 'isIPv6Address', function(){ + expect(6); // Based on IPTest.php > IPv6 deepEqual( mw.util.isIPv6Address( "" ), false, 'Empty string is not an IP' ); @@ -153,6 +186,7 @@ test( 'isIPv6Address', function(){ }); test( 'isIPv4Address', function(){ + expect(3); // Based on IPTest.php > IPv4 deepEqual( mw.util.isIPv4Address( "" ), false, 'Empty string is not an IP' ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.js b/tests/qunit/suites/resources/mediawiki/mediawiki.js index 810fd42da6..150dd782eb 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.js @@ -13,6 +13,7 @@ test( '-- Initial check', function(){ }); test( 'mw.Map', function(){ + expect(20); ok( mw.Map, 'mw.Map defined' ); ok( mw.Map.prototype.get, 'get prototype defined' ); @@ -25,53 +26,57 @@ test( 'mw.Map', function(){ var arry = []; var nummy = 7; - deepEqual( conf.get( 'inexistantKey' ), null, 'Map.get() returns null if selection was a string and the key was not found.' ); - deepEqual( conf.set( 'myKey', 'myValue' ), true, 'Map.set() returns boolean true if a value was set for a valid key string.' ); - deepEqual( conf.set( funky, 'Funky' ), false, 'Map.set() returns boolean false if key was invalid (Function).' ); - deepEqual( conf.set( arry, 'Arry' ), false, 'Map.set() returns boolean false if key was invalid (Array).' ); - deepEqual( conf.set( nummy, 'Nummy' ), false, 'Map.set() returns boolean false if key was invalid (Number).' ); - equal( conf.get( 'myKey' ), 'myValue', 'Map.get() returns a single value value correctly.' ); + deepEqual( conf.get( 'inexistantKey' ), null, 'Map.get() returns null if selection was a string and the key was not found' ); + deepEqual( conf.set( 'myKey', 'myValue' ), true, 'Map.set() returns boolean true if a value was set for a valid key string' ); + deepEqual( conf.set( funky, 'Funky' ), false, 'Map.set() returns boolean false if key was invalid (Function)' ); + deepEqual( conf.set( arry, 'Arry' ), false, 'Map.set() returns boolean false if key was invalid (Array)' ); + deepEqual( conf.set( nummy, 'Nummy' ), false, 'Map.set() returns boolean false if key was invalid (Number)' ); + equal( conf.get( 'myKey' ), 'myValue', 'Map.get() returns a single value value correctly' ); var someValues = { 'foo': 'bar', 'lorem': 'ipsum', 'MediaWiki': true }; - deepEqual( conf.set( someValues ), true, 'Map.set() returns boolean true if multiple values were set by passing an object.' ); + deepEqual( conf.set( someValues ), true, 'Map.set() returns boolean true if multiple values were set by passing an object' ); deepEqual( conf.get( ['foo', 'lorem'] ), { 'foo': 'bar', 'lorem': 'ipsum' - }, 'Map.get() returns multiple values correctly as an object.' ); + }, 'Map.get() returns multiple values correctly as an object' ); deepEqual( conf.get( ['foo', 'notExist'] ), { 'foo': 'bar', 'notExist': null }, 'Map.get() return includes keys that were not found as null values' ); - deepEqual( conf.exists( 'foo' ), true, 'Map.exists() returns boolean true if a key exists.' ); - deepEqual( conf.exists( 'notExist' ), false, 'Map.exists() returns boolean false if a key does not exists.' ); - deepEqual( conf.get() === conf.values, true, 'Map.get() returns the entire values object by reference (if called without arguments).' ); + deepEqual( conf.exists( 'foo' ), true, 'Map.exists() returns boolean true if a key exists' ); + deepEqual( conf.exists( 'notExist' ), false, 'Map.exists() returns boolean false if a key does not exists' ); + deepEqual( conf.get() === conf.values, true, 'Map.get() returns the entire values object by reference (if called without arguments)' ); conf.set( 'globalMapChecker', 'Hi' ); - deepEqual( 'globalMapChecker' in window, false, 'new mw.Map() did not store its values in the global window object by default.' ); - ok( !window.globalMapChecker, 'new mw.Map() did not store its values in the global window object by default.' ); + deepEqual( 'globalMapChecker' in window, false, 'new mw.Map() did not store its values in the global window object by default' ); + ok( !window.globalMapChecker, 'new mw.Map() did not store its values in the global window object by default' ); var globalConf = new mw.Map( true ); globalConf.set( 'anotherGlobalMapChecker', 'Hello' ); - deepEqual( 'anotherGlobalMapChecker' in window, true, 'new mw.Map( true ) did store its values in the global window object.' ) - ok( window.anotherGlobalMapChecker, 'new mw.Map( true ) did store its values in the global window object.' ) + deepEqual( 'anotherGlobalMapChecker' in window, true, 'new mw.Map( true ) did store its values in the global window object' ); + ok( window.anotherGlobalMapChecker, 'new mw.Map( true ) did store its values in the global window object' ); // Clean up delete window.anotherGlobalMapChecker; }); test( 'mw.config', function(){ + expect(1); + deepEqual( mw.config instanceof mw.Map, true, 'mw.config instance of mw.Map' ); }); test( 'mw.messages / mw.message / mw.msg', function(){ + expect(18); + ok( mw.message, 'mw.message defined' ); ok( mw.msg, 'mw.msg defined' ); ok( mw.messages, 'messages defined' ); @@ -80,37 +85,39 @@ test( 'mw.messages / mw.message / mw.msg', function(){ var hello = mw.message( 'hello' ); - equal( hello.format, 'parse', 'Message property "format" defaults to "parse".' ); + equal( hello.format, 'parse', 'Message property "format" defaults to "parse"' ); deepEqual( hello.map === mw.messages, true, 'Message property "map" defaults to the global instance in mw.messages' ); equal( hello.key, 'hello', 'Message property "key" (currect key)' ); - deepEqual( hello.parameters, [], 'Message property "parameters" defaults to an empty array.' ); + deepEqual( hello.parameters, [], 'Message property "parameters" defaults to an empty array' ); // Todo - ok( hello.params, 'Message prototype "params".' ); + ok( hello.params, 'Message prototype "params"' ); hello.format = 'plain'; - equal( hello.toString(), 'Hello awesome world', 'Message.toString() returns the message as a string with the current "format".' ); + equal( hello.toString(), 'Hello awesome world', 'Message.toString() returns the message as a string with the current "format"' ); - equal( hello.escaped(), 'Hello <b>awesome</b> world', 'Message.escaped() returns the escaped message.' ); - equal( hello.format, 'escaped', 'Message.escaped() correctly updated the "format" property.' ); + equal( hello.escaped(), 'Hello <b>awesome</b> world', 'Message.escaped() returns the escaped message' ); + equal( hello.format, 'escaped', 'Message.escaped() correctly updated the "format" property' ); - hello.parse() - equal( hello.format, 'parse', 'Message.parse() correctly updated the "format" property.' ); + hello.parse(); + equal( hello.format, 'parse', 'Message.parse() correctly updated the "format" property' ); hello.plain(); - equal( hello.format, 'plain', 'Message.plain() correctly updated the "format" property.' ); + equal( hello.format, 'plain', 'Message.plain() correctly updated the "format" property' ); - deepEqual( hello.exists(), true, 'Message.exists() returns true for existing messages.' ); + deepEqual( hello.exists(), true, 'Message.exists() returns true for existing messages' ); var goodbye = mw.message( 'goodbye' ); - deepEqual( goodbye.exists(), false, 'Message.exists() returns false for inexisting messages.' ); + deepEqual( goodbye.exists(), false, 'Message.exists() returns false for inexisting messages' ); - equal( goodbye.toString(), '', 'Message.toString() returns if key does not exist.' ); + equal( goodbye.toString(), '', 'Message.toString() returns if key does not exist' ); }); test( 'mw.msg', function(){ + expect(2); + equal( mw.msg( 'hello' ), 'Hello awesome world', 'Gets message with default options (existing message)' ); - equal( mw.msg( 'goodbye' ), '', 'Gets message with default options (inexisting message).' ); + equal( mw.msg( 'goodbye' ), '', 'Gets message with default options (inexisting message)' ); }); test( 'mw.loader', function(){