Adding or adjusting front-end function and variable documentation per our conventions.
authorKrinkle <krinkle@users.mediawiki.org>
Sun, 29 May 2011 02:54:01 +0000 (02:54 +0000)
committerKrinkle <krinkle@users.mediawiki.org>
Sun, 29 May 2011 02:54:01 +0000 (02:54 +0000)
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.

resources/mediawiki.util/mediawiki.util.jpegmeta.js
resources/mediawiki.util/mediawiki.util.js
resources/mediawiki/mediawiki.htmlform.js
resources/mediawiki/mediawiki.js
resources/mediawiki/mediawiki.log.js
tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js
tests/qunit/suites/resources/jquery/jquery.colorUtil.js
tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js
tests/qunit/suites/resources/jquery/jquery.tabIndex.js
tests/qunit/suites/resources/mediawiki.util/mediawiki.util.js
tests/qunit/suites/resources/mediawiki/mediawiki.js

index 08e0748..5e5f338 100644 (file)
        };
        
        /* 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
index ec5c327..6f08fc0 100644 (file)
@@ -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 ) {
                                        // 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 = $( '<a href="#" class="internal" id="togglelink">' ).text( mw.msg( 'hidetoc' ) ).click( function(e){
-                                                               e.preventDefault();
-                                                               mw.util.toggleToc( $(this) );
+                                                       $tocToggleLink = $( '<a href="#" class="internal" id="togglelink">' )
+                                                               .text( mw.msg( 'hidetoc' ) )
+                                                               .click( function(e){
+                                                                       e.preventDefault();
+                                                                       mw.util.toggleToc( $(this) );
                                                        } );
                                                $tocTitle.append( $tocToggleLink.wrap( '<span class="toctoggle">' ).parent().prepend( '&nbsp;[' ).append( ']&nbsp;' ) );
 
                /**
                 * 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();
                 * 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 )
                /**
                 * 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 ) {
                 * 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' );
                /**
                 * 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' );
                        } 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,
                                        } );
                                        return true;
                                } else {
-                                       $tocList.slideUp( 'fast' );
+                                       $tocList.slideUp( 'fast', callback );
                                        $toggleLink.text( mw.msg( 'showtoc' ) );
                                        $.cookie( 'mw_hidetoc', '1', {
                                                expires: 30,
                                        return false;
                                }
                        } else {
-                               return false;
+                               return null;
                        }
                },
 
                 * 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;
                        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-)?(.)\]$/,
 
                /**
                 * 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;
                        } );
                },
 
-               // 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,
 
                /**
                 * 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
                 *       '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 ) {
 
                                } else {
                                        $ul.append( $item );
                                }
-                               
+
 
                                return $item[0];
                        }
                 *
                 * @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 ) {
 
                 * 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 === '' ) {
                                );
                        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 =
index 0b8cf83..1a6acd6 100644 (file)
@@ -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 );
index f36d21c..9bf9506 100644 (file)
@@ -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 <meta name="ResourceLoaderDynamicStyles"> found, inserting dynamically.' );
-                               return $marker = $( '<meta>' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' );
+                               $marker = $( '<meta>' ).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 ) {
index c0f8738..46fd98e 100644 (file)
         *
         * @author Michael Dale <mdale@wikimedia.org>
         * @author Trevor Parscal <tparscal@wikimedia.org>
-        * @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( '<span style="float:right">[' + time + ']</span>' )
                        );
                }
index e0d5b98..6be5212 100644 (file)
@@ -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();
index 5c8f067..9ac289d 100644 (file)
@@ -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 );
 
index b53e062..6fd681f 100644 (file)
@@ -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
index 73a1800..b320d63 100644 (file)
@@ -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 = 
-'<form>\
-       <input tabindex="7" />\
-       <input tabindex="9" />\
-       <textarea tabindex="2">Foobar</textarea>\
-       <textarea tabindex="5">Foobar</textarea>\
-</form>';
+'<form>' +
+       '<input tabindex="7" />' +
+       '<input tabindex="9" />' +
+       '<textarea tabindex="2">Foobar</textarea>' +
+       '<textarea tabindex="5">Foobar</textarea>' +
+'</form>';
        var $testA = $( '<div />' ).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 = 
-'<form>\
-       <input tabindex="7" />\
-       <input tabindex="9" />\
-       <textarea tabindex="2">Foobar</textarea>\
-       <textarea tabindex="5">Foobar</textarea>\
-</form>';
+'<form>' +
+       '<input tabindex="7" />' +
+       '<input tabindex="9" />' +
+       '<textarea tabindex="2">Foobar</textarea>' +
+       '<textarea tabindex="5">Foobar</textarea>' +
+'</form>';
        var $testA = $( '<div />' ).html( testEnvironment ).appendTo( 'body' );
 
        deepEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' );
index cfedac9..68ce17c 100644 (file)
@@ -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 =
+       '<table id="toc" class="toc"><tr><td>' +
+               '<div id="toctitle">' +
+                       '<h2>Contents</h2>' +
+                       '<span class="toctoggle">&nbsp;[<a href="#" class="internal" id="togglelink">Hide</a>&nbsp;]</span>' +
+               '</div>' +
+               '<ul><li></li></ul>' +
+       '</td></tr></table>';   
+       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' );
index 810fd42..150dd78 100644 (file)
@@ -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 <b>awesome</b> world', 'Message.toString() returns the message as a string with the current "format".' );
+       equal( hello.toString(), 'Hello <b>awesome</b> world', 'Message.toString() returns the message as a string with the current "format"' );
 
-       equal( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; world', 'Message.escaped() returns the escaped message.' );
-       equal( hello.format, 'escaped', 'Message.escaped() correctly updated the "format" property.' );
+       equal( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; 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(), '<goodbye>', 'Message.toString() returns <key> if key does not exist.' );
+       equal( goodbye.toString(), '<goodbye>', 'Message.toString() returns <key> if key does not exist' );
 });
 
 test( 'mw.msg', function(){
+       expect(2);
+
        equal( mw.msg( 'hello' ), 'Hello <b>awesome</b> world', 'Gets message with default options (existing message)' );
-       equal( mw.msg( 'goodbye' ), '<goodbye>', 'Gets message with default options (inexisting message).' );
+       equal( mw.msg( 'goodbye' ), '<goodbye>', 'Gets message with default options (inexisting message)' );
 });
 
 test( 'mw.loader', function(){