From 4ac9fa081a7c045f6a9f1cfc529d82423f485b2e Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sun, 8 Dec 2013 09:55:49 +0100 Subject: Update to MediaWiki 1.22.0 --- tests/qunit/QUnitTestResources.php | 4 +- tests/qunit/data/generateJqueryMsgData.php | 4 +- tests/qunit/data/load.mock.php | 3 +- tests/qunit/data/testrunner.js | 29 +- .../resources/jquery/jquery.byteLength.test.js | 24 +- .../resources/jquery/jquery.byteLimit.test.js | 120 ++++---- .../suites/resources/jquery/jquery.client.test.js | 283 +++++++++++++---- .../resources/jquery/jquery.localize.test.js | 10 +- .../jquery/jquery.makeCollapsible.test.js | 287 ++++++++++++++++++ .../resources/jquery/jquery.tablesorter.test.js | 166 +++++++++- .../resources/jquery/jquery.textSelection.test.js | 7 - .../mediawiki.special.recentchanges.test.js | 2 +- .../resources/mediawiki/mediawiki.Title.test.js | 268 ++++++++++++++-- .../mediawiki/mediawiki.jqueryMsg.test.js | 337 ++++++++++++++------- .../suites/resources/mediawiki/mediawiki.test.js | 171 ++++++++++- .../resources/mediawiki/mediawiki.user.test.js | 6 +- .../resources/mediawiki/mediawiki.util.test.js | 91 ++++-- tests/qunit/suites/resources/startup.test.js | 129 ++++++++ 18 files changed, 1609 insertions(+), 332 deletions(-) create mode 100644 tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js create mode 100644 tests/qunit/suites/resources/startup.test.js (limited to 'tests/qunit') diff --git a/tests/qunit/QUnitTestResources.php b/tests/qunit/QUnitTestResources.php index 01072d83..c8743750 100644 --- a/tests/qunit/QUnitTestResources.php +++ b/tests/qunit/QUnitTestResources.php @@ -6,6 +6,7 @@ return array( 'mediawiki.tests.qunit.suites' => array( 'scripts' => array( + 'tests/qunit/suites/resources/startup.test.js', 'tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js', 'tests/qunit/suites/resources/jquery/jquery.byteLength.test.js', 'tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js', @@ -16,6 +17,7 @@ return array( 'tests/qunit/suites/resources/jquery/jquery.hidpi.test.js', 'tests/qunit/suites/resources/jquery/jquery.highlightText.test.js', 'tests/qunit/suites/resources/jquery/jquery.localize.test.js', + 'tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js', 'tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js', 'tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js', 'tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js', @@ -45,6 +47,7 @@ return array( 'jquery.hidpi', 'jquery.highlightText', 'jquery.localize', + 'jquery.makeCollapsible', 'jquery.mwExtension', 'jquery.tabIndex', 'jquery.tablesorter', @@ -61,6 +64,5 @@ return array( 'mediawiki.language', 'mediawiki.cldr', ), - 'position' => 'top', ) ); diff --git a/tests/qunit/data/generateJqueryMsgData.php b/tests/qunit/data/generateJqueryMsgData.php index 604ede81..12e5a2dc 100644 --- a/tests/qunit/data/generateJqueryMsgData.php +++ b/tests/qunit/data/generateJqueryMsgData.php @@ -61,7 +61,7 @@ * */ -require( __DIR__ . '/../../../maintenance/Maintenance.php' ); +require __DIR__ . '/../../../maintenance/Maintenance.php'; class GenerateJqueryMsgData extends Maintenance { @@ -147,4 +147,4 @@ class GenerateJqueryMsgData extends Maintenance { } $maintClass = "GenerateJqueryMsgData"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/tests/qunit/data/load.mock.php b/tests/qunit/data/load.mock.php index 7ff392ab..f6eff77a 100644 --- a/tests/qunit/data/load.mock.php +++ b/tests/qunit/data/load.mock.php @@ -24,6 +24,7 @@ */ header( 'Content-Type: text/javascript; charset=utf-8' ); +require_once __DIR__ . '/../../../includes/json/FormatJson.php'; require_once __DIR__ . '/../../../includes/Xml.php'; $moduleImplementations = array( @@ -50,7 +51,7 @@ if ( isset( $_GET['modules'] ) ) { if ( isset( $moduleImplementations[$module] ) ) { $response .= $moduleImplementations[$module]; } else { - $response .= Xml::encodeJsCall( 'mw.loader.state', array( $module, 'missing' ) ); + $response .= Xml::encodeJsCall( 'mw.loader.state', array( $module, 'missing' ), true ); } } } diff --git a/tests/qunit/data/testrunner.js b/tests/qunit/data/testrunner.js index 62dd81ac..1a2bfa10 100644 --- a/tests/qunit/data/testrunner.js +++ b/tests/qunit/data/testrunner.js @@ -38,6 +38,8 @@ tooltip: 'Enable debug mode in ResourceLoader' } ); + QUnit.config.requireExpects = true; + /** * Load TestSwarm agent */ @@ -48,13 +50,14 @@ // of MediaWiki has actually been configured with the required url to that inject.js // script. By default it is false. if ( QUnit.urlParams.swarmURL && mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) { - document.write( '' ); + jQuery.getScript( QUnit.fixurl( mw.config.get( 'QUnitTestSwarmInjectJSPath' ) ) ); } /** * CompletenessTest + * + * Adds toggle checkbox to header */ - // Adds toggle checkbox to header QUnit.config.urlConfig.push( { id: 'completenesstest', label: 'Run CompletenessTest', @@ -93,8 +96,9 @@ /** * Test environment recommended for all QUnit test modules + * + * Whether to log environment changes to the console */ - // Whether to log environment changes to the console QUnit.config.urlConfig.push( 'mwlogenv' ); /** @@ -347,6 +351,25 @@ assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' ); } ); + QUnit.test( 'Loader status', 2, function ( assert ) { + var i, len, state, + modules = mw.loader.getModuleNames(), + error = [], + missing = []; + + for ( i = 0, len = modules.length; i < len; i++ ) { + state = mw.loader.getState( modules[i] ); + if ( state === 'error' ) { + error.push( modules[i] ); + } else if ( state === 'missing' ) { + missing.push( modules[i] ); + } + } + + assert.deepEqual( error, [], 'Modules in error state' ); + assert.deepEqual( missing, [], 'Modules in missing state' ); + } ); + QUnit.test( 'htmlEqual', 8, function ( assert ) { assert.htmlEqual( '

Child paragraph with A link

Regular textA span
', diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js index e4e579b0..e6aa3aa8 100644 --- a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js @@ -16,20 +16,22 @@ } ); - QUnit.test( 'Special text', 5, function ( assert ) { - // http://en.wikipedia.org/wiki/UTF-8 + QUnit.test( 'Special text', 4, function ( assert ) { + // https://en.wikipedia.org/wiki/UTF-8 var u0024 = '$', + // Cent symbol u00A2 = '\u00A2', + // Euro symbol u20AC = '\u20AC', - u024B62 = '\u024B62', - // The normal one doesn't display properly, try the below which is the same - // according to http://www.fileformat.info/info/unicode/char/24B62/index.htm - u024B62alt = '\uD852\uDF62'; + // Character \U00024B62 (Han script) can't be represented in javascript as a single + // code point, instead it is composed as a surrogate pair of two separate code units. + // http://codepoints.net/U+24B62 + // http://www.fileformat.info/info/unicode/char/24B62/index.htm + u024B62 = '\uD852\uDF62'; - assert.strictEqual( $.byteLength( u0024 ), 1, 'U+0024: 1 byte. $ (dollar sign)' ); - assert.strictEqual( $.byteLength( u00A2 ), 2, 'U+00A2: 2 bytes. \u00A2 (cent sign)' ); - assert.strictEqual( $.byteLength( u20AC ), 3, 'U+20AC: 3 bytes. \u20AC (euro sign)' ); - assert.strictEqual( $.byteLength( u024B62 ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character)' ); - assert.strictEqual( $.byteLength( u024B62alt ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character) - alternative method' ); + assert.strictEqual( $.byteLength( u0024 ), 1, 'U+0024' ); + assert.strictEqual( $.byteLength( u00A2 ), 2, 'U+00A2' ); + assert.strictEqual( $.byteLength( u20AC ), 3, 'U+20AC' ); + assert.strictEqual( $.byteLength( u024B62 ), 4, 'U+024B62 (surrogate pair: \\uD852\\uDF62)' ); } ); }( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js b/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js index c21844eb..22d2af19 100644 --- a/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js @@ -31,55 +31,34 @@ /** * Test factory for $.fn.byteLimit * - * @param $input {jQuery} jQuery object in an input element - * @param hasLimit {Boolean} Wether a limit should apply at all - * @param limit {Number} Limit (if used) otherwise undefined - * The limit should be less than 20 (the sample data's length) + * @param {Object} options + * @param {string} options.description Test name + * @param {jQuery} options.$input jQuery object in an input element + * @param {string} options.sample Sequence of characters to simulate being + * added one by one + * @param {string} options.expected Expected final value of `$input` */ function byteLimitTest( options ) { var opt = $.extend( { description: '', $input: null, sample: '', - hasLimit: false, - expected: '', - limit: null + expected: '' }, options ); - QUnit.asyncTest( opt.description, opt.hasLimit ? 3 : 2, function ( assert ) { + QUnit.asyncTest( opt.description, 1, function ( assert ) { setTimeout( function () { - var rawVal, fn, effectiveVal; - opt.$input.appendTo( '#qunit-fixture' ); // Simulate pressing keys for each of the sample characters addChars( opt.$input, opt.sample ); - rawVal = opt.$input.val(); - fn = opt.$input.data( 'byteLimit.callback' ); - effectiveVal = fn ? fn( rawVal ) : rawVal; - - if ( opt.hasLimit ) { - assert.ltOrEq( - $.byteLength( effectiveVal ), - opt.limit, - 'Prevent keypresses after byteLimit was reached, length never exceeded the limit' - ); - assert.equal( - $.byteLength( rawVal ), - $.byteLength( opt.expected ), - 'Not preventing keypresses too early, length has reached the expected length' - ); - assert.equal( rawVal, opt.expected, 'New value matches the expected string' ); - - } else { - assert.equal( - $.byteLength( effectiveVal ), - $.byteLength( opt.expected ), - 'Unlimited scenarios are not affected, expected length reached' - ); - assert.equal( rawVal, opt.expected, 'New value matches the expected string' ); - } + assert.equal( + opt.$input.val(), + opt.expected, + 'New value matches the expected string' + ); + QUnit.start(); }, 10 ); } ); @@ -89,7 +68,6 @@ description: 'Plain text input', $input: $( '' ), sample: simpleSample, - hasLimit: false, expected: simpleSample } ); @@ -98,7 +76,6 @@ $input: $( '' ) .byteLimit(), sample: simpleSample, - hasLimit: false, expected: simpleSample } ); @@ -108,8 +85,6 @@ .attr( 'maxlength', '10' ) .byteLimit(), sample: simpleSample, - hasLimit: true, - limit: 10, expected: '1234567890' } ); @@ -118,8 +93,6 @@ $input: $( '' ) .byteLimit( 10 ), sample: simpleSample, - hasLimit: true, - limit: 10, expected: '1234567890' } ); @@ -129,8 +102,6 @@ .attr( 'maxlength', '10' ) .byteLimit( 15 ), sample: simpleSample, - hasLimit: true, - limit: 15, expected: '123456789012345' } ); @@ -139,8 +110,6 @@ $input: $( '' ) .byteLimit( 14 ), sample: mbSample, - hasLimit: true, - limit: 14, expected: '1234567890' + U_20AC + '1' } ); @@ -149,8 +118,6 @@ $input: $( '' ) .byteLimit( 12 ), sample: mbSample, - hasLimit: true, - limit: 12, expected: '1234567890' + '12' } ); @@ -158,17 +125,11 @@ description: 'Pass the limit and a callback as input filter', $input: $( '' ) .byteLimit( 6, function ( val ) { - // Invalid title - if ( val === '' ) { - return ''; - } - + var title = mw.Title.newFromText( String( val ) ); // Return without namespace prefix - return new mw.Title( String( val ) ).getMain(); + return title ? title.getMain() : ''; } ), sample: 'User:Sample', - hasLimit: true, - limit: 6, // 'Sample' length expected: 'User:Sample' } ); @@ -177,20 +138,53 @@ $input: $( '' ) .attr( 'maxlength', '6' ) .byteLimit( function ( val ) { - // Invalid title - if ( val === '' ) { - return ''; - } - + var title = mw.Title.newFromText( String( val ) ); // Return without namespace prefix - return new mw.Title( String( val ) ).getMain(); + return title ? title.getMain() : ''; } ), sample: 'User:Sample', - hasLimit: true, - limit: 6, // 'Sample' length expected: 'User:Sample' } ); + byteLimitTest( { + description: 'Pass the limit and a callback as input filter', + $input: $( '' ) + .byteLimit( 6, function ( val ) { + var title = mw.Title.newFromText( String( val ) ); + // Return without namespace prefix + return title ? title.getMain() : ''; + } ), + sample: 'User:Example', + // The callback alters the value to be used to calculeate + // the length. The altered value is "Exampl" which has + // a length of 6, the "e" would exceed the limit. + expected: 'User:Exampl' + } ); + + byteLimitTest( { + description: 'Input filter that increases the length', + $input: $( '' ) + .byteLimit( 10, function ( text ) { + return 'prefix' + text; + } ), + sample: simpleSample, + // Prefix adds 6 characters, limit is reached after 4 + expected: '1234' + } ); + + // Regression tests for bug 41450 + byteLimitTest( { + description: 'Input filter of which the base exceeds the limit', + $input: $( '' ) + .byteLimit( 3, function ( text ) { + return 'prefix' + text; + } ), + sample: simpleSample, + hasLimit: true, + limit: 6, // 'prefix' length + expected: '' + } ); + QUnit.test( 'Confirm properties and attributes set', 4, function ( assert ) { var $el, $elA, $elB; diff --git a/tests/qunit/suites/resources/jquery/jquery.client.test.js b/tests/qunit/suites/resources/jquery/jquery.client.test.js index 88bbf5c4..4c7c3022 100644 --- a/tests/qunit/suites/resources/jquery/jquery.client.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.client.test.js @@ -1,16 +1,11 @@ ( function ( $ ) { - var uacount, uas, testMap; QUnit.module( 'jquery.client', QUnit.newMwEnvironment() ); - /** Number of user-agent defined */ - uacount = 0; - - uas = ( function () { - + var uacount = 0, // Object keyed by userAgent. Value is an array (human-readable name, client-profile object, navigator.platform value) // Info based on results from http://toolserver.org/~krinkle/testswarm/job/174/ - var uas = { + uas = { // Internet Explorer 6 // Internet Explorer 7 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)': { @@ -39,7 +34,7 @@ profile: { name: 'msie', layout: 'trident', - layoutVersion: 'unknown', // should be able to report 6? + layoutVersion: 6, platform: 'win', version: '10.0', versionBase: '10', @@ -50,6 +45,60 @@ rtl: true } }, + // Internet Explorer 11 + 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko': { + title: 'Internet Explorer 11', + platform: 'Win32', + profile: { + name: 'msie', + layout: 'trident', + layoutVersion: 7, + platform: 'win', + version: '11.0', + versionBase: '11', + versionNumber: 11 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, + // Internet Explorer 11 - Windows 8.1 x64 Modern UI + 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; rv:11.0) like Gecko': { + title: 'Internet Explorer 11', + platform: 'Win64', + profile: { + name: 'msie', + layout: 'trident', + layoutVersion: 7, + platform: 'win', + version: '11.0', + versionBase: '11', + versionNumber: 11 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, + // Internet Explorer 11 - Windows 8.1 x64 desktop UI + 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko': { + title: 'Internet Explorer 11', + platform: 'WOW64', + profile: { + name: 'msie', + layout: 'trident', + layoutVersion: 7, + platform: 'win', + version: '11.0', + versionBase: '11', + versionNumber: 11 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Firefox 2 // Firefox 3.5 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19': { @@ -141,6 +190,24 @@ rtl: true } }, + // Iceweasel 15.0.1 + 'Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1 Iceweasel/15.0.1': { + title: 'Iceweasel 15.0.1', + platform: 'Linux', + profile: { + name: 'iceweasel', + layout: 'gecko', + layoutVersion: 20100101, + platform: 'linux', + version: '15.0.1', + versionBase: '15', + versionNumber: 15 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Firefox 5 // Safari 3 // Safari 4 @@ -179,6 +246,42 @@ } }, // Safari 5 + // Safari 6 + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.29.13 (KHTML, like Gecko) Version/6.0.4 Safari/536.29.13': { + title: 'Safari 6', + platform: 'MacIntel', + profile: { + name: 'safari', + layout: 'webkit', + layoutVersion: 536, + platform: 'mac', + version: '6.0.4', + versionBase: '6', + versionNumber: 6 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, + // Safari 6.0.5+ (doesn't have the comma in "KHTML, like Gecko") + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 1084) AppleWebKit/536.30.1 (KHTML like Gecko) Version/6.0.5 Safari/536.30.1': { + title: 'Safari 6', + platform: 'MacIntel', + profile: { + name: 'safari', + layout: 'webkit', + layoutVersion: 536, + platform: 'mac', + version: '6.0.5', + versionBase: '6', + versionNumber: 6 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Opera 10+ 'Opera/9.80 (Windows NT 5.1)': { title: 'Opera 10+ (exact version unspecified)', @@ -215,6 +318,24 @@ rtl: true } }, + // Opera 15 (WebKit-based) + 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.130': { + title: 'Opera 15', + platform: 'Win32', + profile: { + name: 'opera', + layout: 'webkit', + layoutVersion: 537, + platform: 'win', + version: '15.0.1147.130', + versionBase: '15', + versionNumber: 15 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Chrome 5 // Chrome 6 // Chrome 7 @@ -257,6 +378,24 @@ rtl: true } }, + // Android WebKit Browser 2.3 + 'Mozilla/5.0 (Linux; U; Android 2.3.5; en-us; HTC Vision Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1': { + title: 'Android WebKit Browser 2.3', + platform: 'Linux armv7l', + profile: { + name: 'android', + layout: 'webkit', + layoutVersion: 533, + platform: 'linux', + version: '2.3.5', + versionBase: '2', + versionNumber: 2.3 + }, + wikiEditor: { + ltr: true, + rtl: true + } + }, // Bug #34924 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.34 (KHTML, like Gecko) rekonq Safari/534.34': { title: 'Rekonq', @@ -275,28 +414,42 @@ rtl: true } } - }; - $.each( uas, function () { - uacount++; - } ); - return uas; - }() ); - - QUnit.test( 'profile userAgent support', uacount, function ( assert ) { - // Generate a client profile object and compare recursively - var uaTest = function ( rawUserAgent, data ) { - var ret = $.client.profile( { - userAgent: rawUserAgent, - platform: data.platform - } ); - assert.deepEqual( ret, data.profile, 'Client profile support check for ' + data.title + ' (' + data.platform + '): ' + rawUserAgent ); - }; + }, + testMap = { + // Example from WikiEditor + // Make sure to use raw numbers, a string like "7.0" would fail on a + // version 10 browser since in string comparaison "10" is before "7.0" :) + 'ltr': { + 'msie': [['>=', 7.0]], + 'firefox': [['>=', 2]], + 'opera': [['>=', 9.6]], + 'safari': [['>=', 3]], + 'chrome': [['>=', 3]], + 'netscape': [['>=', 9]], + 'blackberry': false, + 'ipod': false, + 'iphone': false + }, + 'rtl': { + 'msie': [['>=', 8]], + 'firefox': [['>=', 2]], + 'opera': [['>=', 9.6]], + 'safari': [['>=', 3]], + 'chrome': [['>=', 3]], + 'netscape': [['>=', 9]], + 'blackberry': false, + 'ipod': false, + 'iphone': false + } + } + ; - // Loop through and run tests - $.each( uas, uaTest ); + // Count test cases + $.each( uas, function () { + uacount++; } ); - QUnit.test( 'profile return validation for current user agent', 7, function ( assert ) { + QUnit.test( 'profile( navObject )', 7, function ( assert ) { var p = $.client.profile(); function unknownOrType( val, type, summary ) { @@ -312,44 +465,58 @@ assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' ); } ); - // Example from WikiEditor - // Make sure to use raw numbers, a string like "7.0" would fail on a - // version 10 browser since in string comparaison "10" is before "7.0" :) - testMap = { - 'ltr': { - 'msie': [['>=', 7.0]], - 'firefox': [['>=', 2]], - 'opera': [['>=', 9.6]], - 'safari': [['>=', 3]], - 'chrome': [['>=', 3]], - 'netscape': [['>=', 9]], - 'blackberry': false, - 'ipod': false, - 'iphone': false - }, - 'rtl': { - 'msie': [['>=', 8]], - 'firefox': [['>=', 2]], - 'opera': [['>=', 9.6]], - 'safari': [['>=', 3]], - 'chrome': [['>=', 3]], - 'netscape': [['>=', 9]], - 'blackberry': false, - 'ipod': false, - 'iphone': false - } - }; + QUnit.test( 'profile( navObject ) - samples', uacount, function ( assert ) { + // Loop through and run tests + $.each( uas, function ( rawUserAgent, data ) { + // Generate a client profile object and compare recursively + var ret = $.client.profile( { + userAgent: rawUserAgent, + platform: data.platform + } ); + assert.deepEqual( ret, data.profile, 'Client profile support check for ' + data.title + ' (' + data.platform + '): ' + rawUserAgent ); + } ); + } ); - QUnit.test( 'test', 1, function ( assert ) { + QUnit.test( 'test( testMap )', 4, function ( assert ) { // .test() uses eval, make sure no exceptions are thrown // then do a basic return value type check - var testMatch = $.client.test( testMap ); + var testMatch = $.client.test( testMap ), + ie7Profile = $.client.profile( { + 'userAgent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', + 'platform': '' + } ); + + assert.equal( typeof testMatch, 'boolean', 'map with ltr/rtl split returns a boolean value' ); + + testMatch = $.client.test( testMap.ltr ); + + assert.equal( typeof testMatch, 'boolean', 'simple map (without ltr/rtl split) returns a boolean value' ); + + assert.equal( $.client.test( { + 'msie': null + }, ie7Profile ), true, 'returns true if any version of a browser are allowed (null)' ); + + assert.equal( $.client.test( { + 'msie': false + }, ie7Profile ), false, 'returns false if all versions of a browser are not allowed (false)' ); + } ); + + QUnit.test( 'test( testMap, exactMatchOnly )', 2, function ( assert ) { + var ie7Profile = $.client.profile( { + 'userAgent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', + 'platform': '' + } ); - assert.equal( typeof testMatch, 'boolean', 'test returns a boolean value' ); + assert.equal( $.client.test( { + 'firefox': [['>=', 2]] + }, ie7Profile, false ), true, 'returns true if browser not found and exactMatchOnly not set' ); + assert.equal( $.client.test( { + 'firefox': [['>=', 2]] + }, ie7Profile, true ), false, 'returns false if browser not found and exactMatchOnly is set' ); } ); - QUnit.test( 'User-agent matches against WikiEditor\'s compatibility map', uacount * 2, function ( assert ) { + QUnit.test( 'test( testMap) - WikiEditor sample', uacount * 2, function ( assert ) { var $body = $( 'body' ), bodyClasses = $body.attr( 'class' ); diff --git a/tests/qunit/suites/resources/jquery/jquery.localize.test.js b/tests/qunit/suites/resources/jquery/jquery.localize.test.js index d3877e05..3ef27903 100644 --- a/tests/qunit/suites/resources/jquery/jquery.localize.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.localize.test.js @@ -38,7 +38,7 @@ // making sure it is actually using text() and attr() (or something with the same effect) // Text escaping - html = '
'; + html = '
'; $lc = $( html ).localize().find( 'span' ); assert.strictEqual( $lc.text(), mw.msg( 'properfoo' ), 'Content is inserted as text, not as html.' ); @@ -63,7 +63,7 @@ var html, $lc, x, sitename = 'Wikipedia'; // Message key prefix - html = '
'; + html = '
'; $lc = $( html ).localize( { prefix: 'foo-' } ).find( 'span' ); @@ -73,7 +73,7 @@ // Variable keys mapping x = 'bar'; - html = '
'; + html = '
'; $lc = $( html ).localize( { keys: { 'title': 'foo-' + x + '-title', @@ -85,7 +85,7 @@ assert.strictEqual( $lc.text(), 'The Bars', 'Variable keys mapping - text' ); // Passing parameteters to mw.msg - html = '
'; + html = '
'; $lc = $( html ).localize( { params: { 'foo-welcome': [sitename, 'yesterday'] @@ -96,7 +96,7 @@ // Combination of options prefix, params and keys x = 'bazz'; - html = '
'; + html = '
'; $lc = $( html ).localize( { prefix: 'foo-', keys: { diff --git a/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js b/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js new file mode 100644 index 00000000..6da56ed2 --- /dev/null +++ b/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js @@ -0,0 +1,287 @@ +( function ( mw, $ ) { + var loremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.'; + + QUnit.module( 'jquery.makeCollapsible', QUnit.newMwEnvironment() ); + + function prepareCollapsible( html, options ) { + return $( $.parseHTML( html ) ) + .appendTo( '#qunit-fixture' ) + // options might be undefined here - this is okay + .makeCollapsible( options ); + } + + // This test is first because if it fails, then almost all of the latter tests are meaningless. + QUnit.asyncTest( 'testing hooks/triggers', 4, function ( assert ) { + var $collapsible, $content, $toggle; + $collapsible = prepareCollapsible( + '
' + loremIpsum + '
' + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + $toggle = $collapsible.find( '.mw-collapsible-toggle' ); + + // In one full collapse-expand cycle, each event will be fired once + + // On collapse... + $collapsible.on( 'beforeCollapse.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'first beforeCollapseExpand: content is visible' ); + } ); + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $content.is( ':hidden' ), 'first afterCollapseExpand: content is hidden' ); + + // On expand... + $collapsible.on( 'beforeExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':hidden' ), 'second beforeCollapseExpand: content is hidden' ); + } ); + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'second afterCollapseExpand: content is visible' ); + + QUnit.start(); + } ); + + // ...expanding happens here + $toggle.trigger( 'click' ); + } ); + + // ...collapsing happens here + $toggle.trigger( 'click' ); + } ); + + QUnit.asyncTest( 'basic operation (
)', 5, function ( assert ) { + var $collapsible, $content, $toggle; + $collapsible = prepareCollapsible( + '
' + loremIpsum + '
' + ); + $content = $collapsible.find( '.mw-collapsible-content' ); + $toggle = $collapsible.find( '.mw-collapsible-toggle' ); + + assert.equal( $content.length, 1, 'content is present' ); + assert.equal( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' ); + + assert.assertTrue( $content.is( ':visible' ), 'content is visible' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' ); + QUnit.start(); + } ); + + $toggle.trigger( 'click' ); + } ); + + $toggle.trigger( 'click' ); + } ); + + QUnit.asyncTest( 'basic operation ()', 7, function ( assert ) { + var $collapsible, $headerRow, $contentRow, $toggle; + $collapsible = prepareCollapsible( + '
' + + '' + + '' + + '' + + '
' + loremIpsum + '' + loremIpsum + '
' + loremIpsum + '' + loremIpsum + '
' + loremIpsum + '' + loremIpsum + '
' + ); + $headerRow = $collapsible.find( 'tr:first' ); + $contentRow = $collapsible.find( 'tr:last' ); + + $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' ); + assert.equal( $toggle.length, 1, 'toggle is added to last cell of first row' ); + + assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' ); + assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $headerRow.is( ':visible' ), 'after collapsing: headerRow is still visible' ); + assert.assertTrue( $contentRow.is( ':hidden' ), 'after collapsing: contentRow is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $headerRow.is( ':visible' ), 'after expanding: headerRow is still visible' ); + assert.assertTrue( $contentRow.is( ':visible' ), 'after expanding: contentRow is visible' ); + QUnit.start(); + } ); + + $toggle.trigger( 'click' ); + } ); + + $toggle.trigger( 'click' ); + } ); + + function listTest( listType, assert ) { + var $collapsible, $toggleItem, $contentItem, $toggle; + $collapsible = prepareCollapsible( + '<' + listType + ' class="mw-collapsible">' + + '
  • ' + loremIpsum + '
  • ' + + '
  • ' + loremIpsum + '
  • ' + + '' + ); + $toggleItem = $collapsible.find( 'li.mw-collapsible-toggle-li:first-child' ); + $contentItem = $collapsible.find( 'li:last' ); + + $toggle = $toggleItem.find( '.mw-collapsible-toggle' ); + assert.equal( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' ); + + assert.assertTrue( $toggleItem.is( ':visible' ), 'toggleItem is visible' ); + assert.assertTrue( $contentItem.is( ':visible' ), 'contentItem is visible' ); + + $collapsible.on( 'afterCollapse.mw-collapsible', function () { + assert.assertTrue( $toggleItem.is( ':visible' ), 'after collapsing: toggleItem is still visible' ); + assert.assertTrue( $contentItem.is( ':hidden' ), 'after collapsing: contentItem is hidden' ); + + $collapsible.on( 'afterExpand.mw-collapsible', function () { + assert.assertTrue( $toggleItem.is( ':visible' ), 'after expanding: toggleItem is still visible' ); + assert.assertTrue( $contentItem.is( ':visible' ), 'after expanding: contentItem is visible' ); + QUnit.start(); + } ); + + $toggle.trigger( 'click' ); + } ); + + $toggle.trigger( 'click' ); + } + + QUnit.asyncTest( 'basic operation (