From 9051f7f06d33bf391f791fc559d16cfb18dd56f5 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Mon, 6 Mar 2017 13:11:48 -0800 Subject: [PATCH] mediawiki.inspect: Fix intermittent test failure Follows-up 15c0382121. Bug: T159751 Change-Id: Ib60521c03e72b1fac694b643c570242d8ee8fab1 --- resources/src/mediawiki/mediawiki.inspect.js | 44 +++++++++++++------ .../mediawiki/mediawiki.inspect.test.js | 19 ++++---- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/resources/src/mediawiki/mediawiki.inspect.js b/resources/src/mediawiki/mediawiki.inspect.js index 3ca9537365..5c2f83f9d2 100644 --- a/resources/src/mediawiki/mediawiki.inspect.js +++ b/resources/src/mediawiki/mediawiki.inspect.js @@ -73,9 +73,9 @@ */ getModuleSize: function ( moduleName ) { var module = mw.loader.moduleRegistry[ moduleName ], - args, i; + args, i, size; - if ( mw.loader.getState( moduleName ) !== 'ready' ) { + if ( module.state !== 'ready' ) { return null; } @@ -83,31 +83,47 @@ return 0; } - // Reverse-engineer the load.php response for this module. - // For example: `mw.loader.implement("example", function(){}, );` + function getFunctionBody( func ) { + return String( func ) + // To ensure a deterministic result, replace the start of the function + // declaration with a fixed string. For example, in Chrome 55, it seems + // V8 seemingly-at-random decides to sometimes put a line break between + // the opening brace and first statement of the function body. T159751. + .replace( /^\s*function\s*\([^)]*\)\s*{\s*/, 'function(){' ) + .replace( /\s*}\s*$/, '}' ); + } + + // Based on the load.php response for this module. + // For example: `mw.loader.implement("example", function(){}, {"css":[".x{color:red}"]});` // @see mw.loader.store.set(). args = [ - JSON.stringify( moduleName ), - // function, array of urls, or eval string - typeof module.script === 'function' ? - String( module.script ) : - JSON.stringify( module.script ), - JSON.stringify( module.style ), - JSON.stringify( module.messages ), - JSON.stringify( module.templates ) + moduleName, + module.script, + module.style, + module.messages, + module.templates ]; // Trim trailing null or empty object, as load.php would have done. // @see ResourceLoader::makeLoaderImplementScript and ResourceLoader::trimArray. i = args.length; while ( i-- ) { - if ( args[ i ] === '{}' || args[ i ] === 'null' ) { + if ( args[ i ] === null || ( $.isPlainObject( args[ i ] ) && $.isEmptyObject( args[ i ] ) ) ) { args.splice( i, 1 ); } else { break; } } - return $.byteLength( args.join( ',' ) ); + size = 0; + for ( i = 0; i < args.length; i++ ) { + if ( typeof args[ i ] === 'function' ) { + size += $.byteLength( getFunctionBody( args[ i ] ) ); + } else { + size += $.byteLength( JSON.stringify( args[ i ] ) ); + } + } + + return size; }, /** diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js index 3bd15c49b2..1f7a5eceb5 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js @@ -1,7 +1,4 @@ ( function ( mw ) { - // Whitespace and serialisation of function bodies - // different in browsers. - var functionSize = String( function () {} ).length; QUnit.module( 'mediawiki.inspect' ); @@ -13,9 +10,9 @@ return mw.loader.using( 'test.inspect.script' ).then( function () { assert.equal( - mw.inspect.getModuleSize( 'test.inspect.script' ) - functionSize, + mw.inspect.getModuleSize( 'test.inspect.script' ), // name, script function - 32, + 43, 'test.inspect.script' ); } ); @@ -30,9 +27,9 @@ return mw.loader.using( 'test.inspect.both' ).then( function () { assert.equal( - mw.inspect.getModuleSize( 'test.inspect.both' ) - functionSize, + mw.inspect.getModuleSize( 'test.inspect.both' ), // name, script function, styles object - 54, + 64, 'test.inspect.both' ); } ); @@ -48,9 +45,9 @@ return mw.loader.using( 'test.inspect.scriptmsg' ).then( function () { assert.equal( - mw.inspect.getModuleSize( 'test.inspect.scriptmsg' ) - functionSize, + mw.inspect.getModuleSize( 'test.inspect.scriptmsg' ), // name, script function, empty styles object, messages object - 65, + 74, 'test.inspect.scriptmsg' ); } ); @@ -67,9 +64,9 @@ return mw.loader.using( 'test.inspect.all' ).then( function () { assert.equal( - mw.inspect.getModuleSize( 'test.inspect.all' ) - functionSize, + mw.inspect.getModuleSize( 'test.inspect.all' ), // name, script function, styles object, messages object, templates object - 118, + 126, 'test.inspect.all' ); } ); -- 2.20.1