diff options
Diffstat (limited to 'tests/qunit/suites/resources/jquery')
15 files changed, 0 insertions, 3316 deletions
diff --git a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js b/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js deleted file mode 100644 index e1895248..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js +++ /dev/null @@ -1,58 +0,0 @@ -( function ( $ ) { - - QUnit.module( 'jquery.autoEllipsis', QUnit.newMwEnvironment() ); - - function createWrappedDiv( text, width ) { - var $wrapper = $( '<div>' ).css( 'width', width ), - $div = $( '<div>' ).text( text ); - $wrapper.append( $div ); - return $wrapper; - } - - function findDivergenceIndex( a, b ) { - var i = 0; - while ( i < a.length && i < b.length && a[i] === b[i] ) { - i++; - } - return i; - } - - QUnit.test( 'Position right', 4, function ( assert ) { - // We need this thing to be visible, so append it to the DOM - var $span, spanText, d, spanTextNew, - origText = 'This is a really long random string and there is no way it fits in 100 pixels.', - $wrapper = createWrappedDiv( origText, '100px' ); - - $( '#qunit-fixture' ).append( $wrapper ); - $wrapper.autoEllipsis( { position: 'right' } ); - - // Verify that, and only one, span element was created - $span = $wrapper.find( '> span' ); - assert.strictEqual( $span.length, 1, 'autoEllipsis wrapped the contents in a span element' ); - - // Check that the text fits by turning on word wrapping - $span.css( 'whiteSpace', 'nowrap' ); - assert.ltOrEq( - $span.width(), - $span.parent().width(), - 'Text fits (making the span "white-space: nowrap" does not make it wider than its parent)' - ); - - // Add two characters using scary black magic - spanText = $span.text(); - d = findDivergenceIndex( origText, spanText ); - spanTextNew = spanText.substr( 0, d ) + origText[d] + origText[d] + '...'; - - assert.gt( spanTextNew.length, spanText.length, 'Verify that the new span-length is indeed greater' ); - - // Put this text in the span and verify it doesn't fit - $span.text( spanTextNew ); - // In IE6 width works like min-width, allow IE6's width to be "equal to" - if ( $.browser.msie && Number( $.browser.version ) === 6 ) { - assert.gtOrEq( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more) - IE6: Maybe equal to as well due to width behaving like min-width in IE6' ); - } else { - assert.gt( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more)' ); - } - } ); - -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js deleted file mode 100644 index e6aa3aa8..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js +++ /dev/null @@ -1,37 +0,0 @@ -( function ( $ ) { - QUnit.module( 'jquery.byteLength', QUnit.newMwEnvironment() ); - - QUnit.test( 'Simple text', 5, function ( assert ) { - var azLc = 'abcdefghijklmnopqrstuvwxyz', - azUc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', - num = '0123456789', - x = '*', - space = ' '; - - assert.equal( $.byteLength( azLc ), 26, 'Lowercase a-z' ); - assert.equal( $.byteLength( azUc ), 26, 'Uppercase A-Z' ); - assert.equal( $.byteLength( num ), 10, 'Numbers 0-9' ); - assert.equal( $.byteLength( x ), 1, 'An asterisk' ); - assert.equal( $.byteLength( space ), 3, '3 spaces' ); - - } ); - - QUnit.test( 'Special text', 4, function ( assert ) { - // https://en.wikipedia.org/wiki/UTF-8 - var u0024 = '$', - // Cent symbol - u00A2 = '\u00A2', - // Euro symbol - u20AC = '\u20AC', - // 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' ); - 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 deleted file mode 100644 index 22d2af19..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js +++ /dev/null @@ -1,252 +0,0 @@ -( function ( $, mw ) { - var simpleSample, U_20AC, mbSample; - - QUnit.module( 'jquery.byteLimit', QUnit.newMwEnvironment() ); - - // Simple sample (20 chars, 20 bytes) - simpleSample = '12345678901234567890'; - - // 3 bytes (euro-symbol) - U_20AC = '\u20AC'; - - // Multi-byte sample (22 chars, 26 bytes) - mbSample = '1234567890' + U_20AC + '1234567890' + U_20AC; - - // Basic sendkey-implementation - function addChars( $input, charstr ) { - var c, len; - - function x( $input, i ) { - // Add character to the value - return $input.val() + charstr.charAt( i ); - } - - for ( c = 0, len = charstr.length; c < len; c += 1 ) { - $input - .val( x( $input, c ) ) - .trigger( 'change' ); - } - } - - /** - * Test factory for $.fn.byteLimit - * - * @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: '', - expected: '' - }, options ); - - QUnit.asyncTest( opt.description, 1, function ( assert ) { - setTimeout( function () { - opt.$input.appendTo( '#qunit-fixture' ); - - // Simulate pressing keys for each of the sample characters - addChars( opt.$input, opt.sample ); - - assert.equal( - opt.$input.val(), - opt.expected, - 'New value matches the expected string' - ); - - QUnit.start(); - }, 10 ); - } ); - } - - byteLimitTest( { - description: 'Plain text input', - $input: $( '<input type="text"/>' ), - sample: simpleSample, - expected: simpleSample - } ); - - byteLimitTest( { - description: 'Plain text input. Calling byteLimit with no parameters and no maxlength attribute (bug 36310)', - $input: $( '<input type="text"/>' ) - .byteLimit(), - sample: simpleSample, - expected: simpleSample - } ); - - byteLimitTest( { - description: 'Limit using the maxlength attribute', - $input: $( '<input type="text"/>' ) - .attr( 'maxlength', '10' ) - .byteLimit(), - sample: simpleSample, - expected: '1234567890' - } ); - - byteLimitTest( { - description: 'Limit using a custom value', - $input: $( '<input type="text"/>' ) - .byteLimit( 10 ), - sample: simpleSample, - expected: '1234567890' - } ); - - byteLimitTest( { - description: 'Limit using a custom value, overriding maxlength attribute', - $input: $( '<input type="text"/>' ) - .attr( 'maxlength', '10' ) - .byteLimit( 15 ), - sample: simpleSample, - expected: '123456789012345' - } ); - - byteLimitTest( { - description: 'Limit using a custom value (multibyte)', - $input: $( '<input type="text"/>' ) - .byteLimit( 14 ), - sample: mbSample, - expected: '1234567890' + U_20AC + '1' - } ); - - byteLimitTest( { - description: 'Limit using a custom value (multibyte) overlapping a byte', - $input: $( '<input type="text"/>' ) - .byteLimit( 12 ), - sample: mbSample, - expected: '1234567890' + '12' - } ); - - byteLimitTest( { - description: 'Pass the limit and a callback as input filter', - $input: $( '<input type="text"/>' ) - .byteLimit( 6, function ( val ) { - var title = mw.Title.newFromText( String( val ) ); - // Return without namespace prefix - return title ? title.getMain() : ''; - } ), - sample: 'User:Sample', - expected: 'User:Sample' - } ); - - byteLimitTest( { - description: 'Limit using the maxlength attribute and pass a callback as input filter', - $input: $( '<input type="text"/>' ) - .attr( 'maxlength', '6' ) - .byteLimit( function ( val ) { - var title = mw.Title.newFromText( String( val ) ); - // Return without namespace prefix - return title ? title.getMain() : ''; - } ), - sample: 'User:Sample', - expected: 'User:Sample' - } ); - - byteLimitTest( { - description: 'Pass the limit and a callback as input filter', - $input: $( '<input type="text"/>' ) - .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: $( '<input type="text"/>' ) - .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: $( '<input type="text"/>' ) - .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; - - $el = $( '<input type="text"/>' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ) - .byteLimit(); - - assert.strictEqual( $el.attr( 'maxlength' ), '7', 'maxlength attribute unchanged for simple limit' ); - - $el = $( '<input type="text"/>' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ) - .byteLimit( 12 ); - - assert.strictEqual( $el.attr( 'maxlength' ), '12', 'maxlength attribute updated for custom limit' ); - - $el = $( '<input type="text"/>' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ) - .byteLimit( 12, function ( val ) { - return val; - } ); - - assert.strictEqual( $el.attr( 'maxlength' ), undefined, 'maxlength attribute removed for limit with callback' ); - - $elA = $( '<input type="text"/>' ) - .addClass( 'mw-test-byteLimit-foo' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ); - - $elB = $( '<input type="text"/>' ) - .addClass( 'mw-test-byteLimit-foo' ) - .attr( 'maxlength', '12' ) - .appendTo( '#qunit-fixture' ); - - $el = $( '.mw-test-byteLimit-foo' ); - - assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' ); - - $el.byteLimit(); - } ); - - QUnit.test( 'Trim from insertion when limit exceeded', 2, function ( assert ) { - var $el; - - // Use a new <input /> because the bug only occurs on the first time - // the limit it reached (bug 40850) - $el = $( '<input type="text"/>' ) - .appendTo( '#qunit-fixture' ) - .byteLimit( 3 ) - .val( 'abc' ).trigger( 'change' ) - .val( 'zabc' ).trigger( 'change' ); - - assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 0), not the end' ); - - $el = $( '<input type="text"/>' ) - .appendTo( '#qunit-fixture' ) - .byteLimit( 3 ) - .val( 'abc' ).trigger( 'change' ) - .val( 'azbc' ).trigger( 'change' ); - - assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 1), not the end' ); - } ); -}( jQuery, mediaWiki ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.client.test.js b/tests/qunit/suites/resources/jquery/jquery.client.test.js deleted file mode 100644 index 4c7c3022..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.client.test.js +++ /dev/null @@ -1,542 +0,0 @@ -( function ( $ ) { - - QUnit.module( 'jquery.client', QUnit.newMwEnvironment() ); - - 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/ - uas = { - // Internet Explorer 6 - // Internet Explorer 7 - 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)': { - title: 'Internet Explorer 7', - platform: 'Win32', - profile: { - name: 'msie', - layout: 'trident', - layoutVersion: 'unknown', - platform: 'win', - version: '7.0', - versionBase: '7', - versionNumber: 7 - }, - wikiEditor: { - ltr: true, - rtl: false - } - }, - // Internet Explorer 8 - // Internet Explorer 9 - // Internet Explorer 10 - 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)': { - title: 'Internet Explorer 10', - platform: 'Win32', - profile: { - name: 'msie', - layout: 'trident', - layoutVersion: 6, - platform: 'win', - version: '10.0', - versionBase: '10', - versionNumber: 10 - }, - wikiEditor: { - ltr: true, - 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': { - title: 'Firefox 3.5', - platform: 'MacIntel', - profile: { - name: 'firefox', - layout: 'gecko', - layoutVersion: 20110420, - platform: 'mac', - version: '3.5.19', - versionBase: '3', - versionNumber: 3.5 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 3.6 - 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/10.10 (maverick) Firefox/3.6.17': { - title: 'Firefox 3.6', - platform: 'Linux i686', - profile: { - name: 'firefox', - layout: 'gecko', - layoutVersion: 20110422, - platform: 'linux', - version: '3.6.17', - versionBase: '3', - versionNumber: 3.6 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 4 - 'Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1': { - title: 'Firefox 4', - platform: 'Win32', - profile: { - name: 'firefox', - layout: 'gecko', - layoutVersion: 20100101, - platform: 'win', - version: '4.0.1', - versionBase: '4', - versionNumber: 4 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 10 nightly build - 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0a1) Gecko/20111103 Firefox/10.0a1': { - title: 'Firefox 10 nightly', - platform: 'Linux', - profile: { - name: 'firefox', - layout: 'gecko', - layoutVersion: 20111103, - platform: 'linux', - version: '10.0a1', - versionBase: '10', - versionNumber: 10 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Iceweasel 10.0.6 - 'Mozilla/5.0 (X11; Linux i686; rv:10.0.6) Gecko/20100101 Iceweasel/10.0.6': { - title: 'Iceweasel 10.0.6', - platform: 'Linux', - profile: { - name: 'iceweasel', - layout: 'gecko', - layoutVersion: 20100101, - platform: 'linux', - version: '10.0.6', - versionBase: '10', - versionNumber: 10 - }, - wikiEditor: { - ltr: true, - 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 - 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; nl-nl) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7': { - title: 'Safari 4', - platform: 'MacIntel', - profile: { - name: 'safari', - layout: 'webkit', - layoutVersion: 531, - platform: 'mac', - version: '4.0.5', - versionBase: '4', - versionNumber: 4 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - 'Mozilla/5.0 (Windows; U; Windows NT 6.0; cs-CZ) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7': { - title: 'Safari 4', - platform: 'Win32', - profile: { - name: 'safari', - layout: 'webkit', - layoutVersion: 533, - platform: 'win', - version: '4.0.5', - versionBase: '4', - versionNumber: 4 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // 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)', - platform: 'Win32', - profile: { - name: 'opera', - layout: 'presto', - layoutVersion: 'unknown', - platform: 'win', - version: '10', - versionBase: '10', - versionNumber: 10 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Opera 12 - 'Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.11': { - title: 'Opera 12', - platform: 'Win32', - profile: { - name: 'opera', - layout: 'presto', - layoutVersion: 'unknown', - platform: 'win', - version: '12.11', - versionBase: '12', - versionNumber: 12.11 - }, - wikiEditor: { - ltr: true, - 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 - // Chrome 8 - // Chrome 9 - // Chrome 10 - // Chrome 11 - // Chrome 12 - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30': { - title: 'Chrome 12', - platform: 'MacIntel', - profile: { - name: 'chrome', - layout: 'webkit', - layoutVersion: 534, - platform: 'mac', - version: '12.0.742.112', - versionBase: '12', - versionNumber: 12 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30': { - title: 'Chrome 12', - platform: 'Linux i686', - profile: { - name: 'chrome', - layout: 'webkit', - layoutVersion: 534, - platform: 'linux', - version: '12.0.742.68', - versionBase: '12', - versionNumber: 12 - }, - wikiEditor: { - ltr: true, - 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', - platform: 'Linux i686', - profile: { - name: 'rekonq', - layout: 'webkit', - layoutVersion: 534, - platform: 'linux', - version: '534.34', - versionBase: '534', - versionNumber: 534.34 - }, - wikiEditor: { - ltr: true, - rtl: true - } - } - }, - 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 - } - } - ; - - // Count test cases - $.each( uas, function () { - uacount++; - } ); - - QUnit.test( 'profile( navObject )', 7, function ( assert ) { - var p = $.client.profile(); - - function unknownOrType( val, type, summary ) { - assert.ok( typeof val === type || val === 'unknown', summary ); - } - - assert.equal( typeof p, 'object', 'profile returns an object' ); - unknownOrType( p.layout, 'string', 'p.layout is a string (or "unknown")' ); - unknownOrType( p.layoutVersion, 'number', 'p.layoutVersion is a number (or "unknown")' ); - unknownOrType( p.platform, 'string', 'p.platform is a string (or "unknown")' ); - unknownOrType( p.version, 'string', 'p.version is a string (or "unknown")' ); - unknownOrType( p.versionBase, 'string', 'p.versionBase is a string (or "unknown")' ); - assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' ); - } ); - - 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( 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 ), - 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( $.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( 'test( testMap) - WikiEditor sample', uacount * 2, function ( assert ) { - var $body = $( 'body' ), - bodyClasses = $body.attr( 'class' ); - - // Loop through and run tests - $.each( uas, function ( agent, data ) { - $.each( ['ltr', 'rtl'], function ( i, dir ) { - var profile, testMatch; - $body.removeClass( 'ltr rtl' ).addClass( dir ); - profile = $.client.profile( { - userAgent: agent, - platform: data.platform - } ); - testMatch = $.client.test( testMap, profile ); - $body.removeClass( dir ); - - assert.equal( testMatch, data.wikiEditor[dir], 'testing comparison based on ' + dir + ', ' + agent ); - } ); - } ); - - // Restore body classes - $body.attr( 'class', bodyClasses ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js b/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js deleted file mode 100644 index 39ae363c..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js +++ /dev/null @@ -1,63 +0,0 @@ -( function ( $ ) { - QUnit.module( 'jquery.colorUtil', QUnit.newMwEnvironment() ); - - QUnit.test( 'getRGB', 18, function ( assert ) { - assert.strictEqual( $.colorUtil.getRGB(), undefined, 'No arguments' ); - assert.strictEqual( $.colorUtil.getRGB( '' ), undefined, 'Empty string' ); - assert.deepEqual( $.colorUtil.getRGB( [0, 100, 255] ), [0, 100, 255], 'Parse array of rgb values' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0,100,255)' ), [0, 100, 255], 'Parse simple rgb string' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0, 100, 255)' ), [0, 100, 255], 'Parse simple rgb string with spaces' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%,20%,40%)' ), [0, 51, 102], 'Parse rgb string with percentages' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%, 20%, 40%)' ), [0, 51, 102], 'Parse rgb string with percentages and spaces' ); - assert.deepEqual( $.colorUtil.getRGB( '#f2ddee' ), [242, 221, 238], 'Hex string: 6 char lowercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#f2DDEE' ), [242, 221, 238], 'Hex string: 6 char uppercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#f2DdEe' ), [242, 221, 238], 'Hex string: 6 char mixed' ); - assert.deepEqual( $.colorUtil.getRGB( '#eee' ), [238, 238, 238], 'Hex string: 3 char lowercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#EEE' ), [238, 238, 238], 'Hex string: 3 char uppercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#eEe' ), [238, 238, 238], 'Hex string: 3 char mixed' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgba(0, 0, 0, 0)' ), [255, 255, 255], 'Zero rgba for Safari 3; Transparent (whitespace)' ); - - // Perhaps this is a bug in colorUtil, but it is the current behavior so, let's keep - // track of it, so we will know in case it would ever change. - assert.strictEqual( $.colorUtil.getRGB( 'rgba(0,0,0,0)' ), undefined, 'Zero rgba without whitespace' ); - - assert.deepEqual( $.colorUtil.getRGB( 'lightGreen' ), [144, 238, 144], 'Color names (lightGreen)' ); - assert.deepEqual( $.colorUtil.getRGB( 'transparent' ), [255, 255, 255], 'Color names (transparent)' ); - assert.strictEqual( $.colorUtil.getRGB( 'mediaWiki' ), undefined, 'Inexisting color name' ); - } ); - - QUnit.test( 'rgbToHsl', 1, function ( assert ) { - var hsl, ret; - - // Cross-browser differences in decimals... - // Round to two decimals so they can be more reliably checked. - function dualDecimals( a ) { - return Math.round( a * 100 ) / 100; - } - - // Re-create the rgbToHsl return array items, limited to two decimals. - hsl = $.colorUtil.rgbToHsl( 144, 238, 144 ); - ret = [ dualDecimals( hsl[0] ), dualDecimals( hsl[1] ), dualDecimals( hsl[2] ) ]; - - assert.deepEqual( ret, [0.33, 0.73, 0.75], 'rgb(144, 238, 144): hsl(0.33, 0.73, 0.75)' ); - } ); - - QUnit.test( 'hslToRgb', 1, function ( assert ) { - var rgb, ret; - rgb = $.colorUtil.hslToRgb( 0.3, 0.7, 0.8 ); - - // Re-create the hslToRgb return array items, rounded to whole numbers. - ret = [ Math.round( rgb[0] ), Math.round( rgb[1] ), Math.round( rgb[2] ) ]; - - assert.deepEqual( ret, [183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' ); - } ); - - QUnit.test( 'getColorBrightness', 2, function ( assert ) { - var a, b; - a = $.colorUtil.getColorBrightness( 'red', +0.1 ); - assert.equal( a, 'rgb(255,50,50)', 'Start with named color "red", brighten 10%' ); - - b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 ); - assert.equal( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js b/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js deleted file mode 100644 index 234b19cb..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js +++ /dev/null @@ -1,37 +0,0 @@ -( function ( $ ) { - QUnit.asyncTest( 'jquery.delayedBind with data option', 2, function ( assert ) { - var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ), - data = { - magic: 'beeswax' - }, - delay = 50; - - $fixture.delayedBind( delay, 'testevent', data, function ( e ) { - assert.ok( true, 'testevent fired' ); - assert.ok( e.data === data, 'data is passed through delayedBind' ); - QUnit.start(); - } ); - - // We'll trigger it thrice, but it should only happen once. - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - } ); - - QUnit.asyncTest( 'jquery.delayedBind without data option', 1, function ( assert ) { - var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ), - delay = 50; - - $fixture.delayedBind( delay, 'testevent', function () { - assert.ok( true, 'testevent fired' ); - QUnit.start(); - } ); - - // We'll trigger it thrice, but it should only happen once. - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js b/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js deleted file mode 100644 index 0b7e87ee..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js +++ /dev/null @@ -1,13 +0,0 @@ -( function ( $ ) { - QUnit.module( 'jquery.getAttrs', QUnit.newMwEnvironment() ); - - QUnit.test( 'Check', 1, function ( assert ) { - var attrs = { - foo: 'bar', - 'class': 'lorem' - }, - $el = $( '<div>' ).attr( attrs ); - - assert.deepEqual( $el.getAttrs(), attrs, 'getAttrs() return object should match the attributes set, no more, no less' ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js b/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js deleted file mode 100644 index 906369ee..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js +++ /dev/null @@ -1,22 +0,0 @@ -( function ( $ ) { - QUnit.module( 'jquery.hidpi', QUnit.newMwEnvironment() ); - - QUnit.test( 'devicePixelRatio', 1, function ( assert ) { - var devicePixelRatio = $.devicePixelRatio(); - assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' ); - } ); - - QUnit.test( 'matchSrcSet', 6, function ( assert ) { - var srcset = 'onefive.png 1.5x, two.png 2x'; - - // Nice exact matches - assert.equal( $.matchSrcSet( 1, srcset ), null, '1.0 gives no match' ); - assert.equal( $.matchSrcSet( 1.5, srcset ), 'onefive.png', '1.5 gives match' ); - assert.equal( $.matchSrcSet( 2, srcset ), 'two.png', '2 gives match' ); - - // Non-exact matches; should return the next-biggest specified - assert.equal( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' ); - assert.equal( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' ); - assert.equal( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js b/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js deleted file mode 100644 index e1fb96dc..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js +++ /dev/null @@ -1,235 +0,0 @@ -( function ( $ ) { - QUnit.module( 'jquery.highlightText', QUnit.newMwEnvironment() ); - - QUnit.test( 'Check', function ( assert ) { - var $fixture, cases = [ - { - desc: 'Test 001', - text: 'Blue Öyster Cult', - highlight: 'Blue', - expected: '<span class="highlight">Blue</span> Öyster Cult' - }, - { - desc: 'Test 002', - text: 'Blue Öyster Cult', - highlight: 'Blue ', - expected: '<span class="highlight">Blue</span> Öyster Cult' - }, - { - desc: 'Test 003', - text: 'Blue Öyster Cult', - highlight: 'Blue Ö', - expected: '<span class="highlight">Blue</span> <span class="highlight">Ö</span>yster Cult' - }, - { - desc: 'Test 004', - text: 'Blue Öyster Cult', - highlight: 'Blue Öy', - expected: '<span class="highlight">Blue</span> <span class="highlight">Öy</span>ster Cult' - }, - { - desc: 'Test 005', - text: 'Blue Öyster Cult', - highlight: ' Blue', - expected: '<span class="highlight">Blue</span> Öyster Cult' - }, - { - desc: 'Test 006', - text: 'Blue Öyster Cult', - highlight: ' Blue ', - expected: '<span class="highlight">Blue</span> Öyster Cult' - }, - { - desc: 'Test 007', - text: 'Blue Öyster Cult', - highlight: ' Blue Ö', - expected: '<span class="highlight">Blue</span> <span class="highlight">Ö</span>yster Cult' - }, - { - desc: 'Test 008', - text: 'Blue Öyster Cult', - highlight: ' Blue Öy', - expected: '<span class="highlight">Blue</span> <span class="highlight">Öy</span>ster Cult' - }, - { - desc: 'Test 009: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Österreich', - expected: '<span class="highlight">Österreich</span>' - }, - { - desc: 'Test 010: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Ö', - expected: '<span class="highlight">Ö</span>sterreich' - }, - { - desc: 'Test 011: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Öst', - expected: '<span class="highlight">Öst</span>erreich' - }, - { - desc: 'Test 012: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Oe', - expected: 'Österreich' - }, - { - desc: 'Test 013: Highlighter broken on punctuation mark?', - text: 'So good. To be there', - highlight: 'good', - expected: 'So <span class="highlight">good</span>. To be there' - }, - { - desc: 'Test 014: Highlighter broken on space?', - text: 'So good. To be there', - highlight: 'be', - expected: 'So good. To <span class="highlight">be</span> there' - }, - { - desc: 'Test 015: Highlighter broken on space?', - text: 'So good. To be there', - highlight: ' be', - expected: 'So good. To <span class="highlight">be</span> there' - }, - { - desc: 'Test 016: Highlighter broken on space?', - text: 'So good. To be there', - highlight: 'be ', - expected: 'So good. To <span class="highlight">be</span> there' - }, - { - desc: 'Test 017: Highlighter broken on space?', - text: 'So good. To be there', - highlight: ' be ', - expected: 'So good. To <span class="highlight">be</span> there' - }, - { - desc: 'Test 018: en de Highlighter broken on special character at the end?', - text: 'So good. xbß', - highlight: 'xbß', - expected: 'So good. <span class="highlight">xbß</span>' - }, - { - desc: 'Test 019: en de Highlighter broken on special character at the end?', - text: 'So good. xbß.', - highlight: 'xbß.', - expected: 'So good. <span class="highlight">xbß.</span>' - }, - { - desc: 'Test 020: RTL he Hebrew', - text: 'חסיד אומות העולם', - highlight: 'חסיד אומות העולם', - expected: '<span class="highlight">חסיד</span> <span class="highlight">אומות</span> <span class="highlight">העולם</span>' - }, - { - desc: 'Test 021: RTL he Hebrew', - text: 'חסיד אומות העולם', - highlight: 'חסי', - expected: '<span class="highlight">חסי</span>ד אומות העולם' - }, - { - desc: 'Test 022: ja Japanese', - text: '諸国民の中の正義の人', - highlight: '諸国民の中の正義の人', - expected: '<span class="highlight">諸国民の中の正義の人</span>' - }, - { - desc: 'Test 023: ja Japanese', - text: '諸国民の中の正義の人', - highlight: '諸国', - expected: '<span class="highlight">諸国</span>民の中の正義の人' - }, - { - desc: 'Test 024: fr French text and « french quotes » (guillemets)', - text: '« L\'oiseau est sur l’île »', - highlight: '« L\'oiseau est sur l’île »', - expected: '<span class="highlight">«</span> <span class="highlight">L\'oiseau</span> <span class="highlight">est</span> <span class="highlight">sur</span> <span class="highlight">l’île</span> <span class="highlight">»</span>' - }, - { - desc: 'Test 025: fr French text and « french quotes » (guillemets)', - text: '« L\'oiseau est sur l’île »', - highlight: '« L\'oise', - expected: '<span class="highlight">«</span> <span class="highlight">L\'oise</span>au est sur l’île »' - }, - { - desc: 'Test 025a: fr French text and « french quotes » (guillemets) - does it match the single strings "«" and "L" separately?', - text: '« L\'oiseau est sur l’île »', - highlight: '« L', - expected: '<span class="highlight">«</span> <span class="highlight">L</span>\'oiseau est sur <span class="highlight">l</span>’île »' - }, - { - desc: 'Test 026: ru Russian', - text: 'Праведники мира', - highlight: 'Праведники мира', - expected: '<span class="highlight">Праведники</span> <span class="highlight">мира</span>' - }, - { - desc: 'Test 027: ru Russian', - text: 'Праведники мира', - highlight: 'Праве', - expected: '<span class="highlight">Праве</span>дники мира' - }, - { - desc: 'Test 028 ka Georgian', - text: 'მთავარი გვერდი', - highlight: 'მთავარი გვერდი', - expected: '<span class="highlight">მთავარი</span> <span class="highlight">გვერდი</span>' - }, - { - desc: 'Test 029 ka Georgian', - text: 'მთავარი გვერდი', - highlight: 'მთა', - expected: '<span class="highlight">მთა</span>ვარი გვერდი' - }, - { - desc: 'Test 030 hy Armenian', - text: 'Նոնա Գափրինդաշվիլի', - highlight: 'Նոնա Գափրինդաշվիլի', - expected: '<span class="highlight">Նոնա</span> <span class="highlight">Գափրինդաշվիլի</span>' - }, - { - desc: 'Test 031 hy Armenian', - text: 'Նոնա Գափրինդաշվիլի', - highlight: 'Նոն', - expected: '<span class="highlight">Նոն</span>ա Գափրինդաշվիլի' - }, - { - desc: 'Test 032: th Thai', - text: 'พอล แอร์ดิช', - highlight: 'พอล แอร์ดิช', - expected: '<span class="highlight">พอล</span> <span class="highlight">แอร์ดิช</span>' - }, - { - desc: 'Test 033: th Thai', - text: 'พอล แอร์ดิช', - highlight: 'พอ', - expected: '<span class="highlight">พอ</span>ล แอร์ดิช' - }, - { - desc: 'Test 034: RTL ar Arabic', - text: 'بول إيردوس', - highlight: 'بول إيردوس', - expected: '<span class="highlight">بول</span> <span class="highlight">إيردوس</span>' - }, - { - desc: 'Test 035: RTL ar Arabic', - text: 'بول إيردوس', - highlight: 'بو', - expected: '<span class="highlight">بو</span>ل إيردوس' - } - ]; - QUnit.expect( cases.length ); - - $.each( cases, function ( i, item ) { - $fixture = $( '<p>' ).text( item.text ).highlightText( item.highlight ); - assert.equal( - $fixture.html(), - // Re-parse to normalize - $( '<p>' ).html( item.expected ).html(), - item.desc || undefined - ); - } ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.localize.test.js b/tests/qunit/suites/resources/jquery/jquery.localize.test.js deleted file mode 100644 index 3ef27903..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.localize.test.js +++ /dev/null @@ -1,135 +0,0 @@ -( function ( $, mw ) { - QUnit.module( 'jquery.localize', QUnit.newMwEnvironment() ); - - QUnit.test( 'Handle basic replacements', 4, function ( assert ) { - var html, $lc; - mw.messages.set( 'basic', 'Basic stuff' ); - - // Tag: html:msg - html = '<div><span><html:msg key="basic" /></span></div>'; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.text(), 'Basic stuff', 'Tag: html:msg' ); - - // Attribute: title-msg - html = '<div><span title-msg="basic"></span></div>'; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), 'Basic stuff', 'Attribute: title-msg' ); - - // Attribute: alt-msg - html = '<div><span alt-msg="basic"></span></div>'; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.attr( 'alt' ), 'Basic stuff', 'Attribute: alt-msg' ); - - // Attribute: placeholder-msg - html = '<div><input placeholder-msg="basic" /></div>'; - $lc = $( html ).localize().find( 'input' ); - - assert.strictEqual( $lc.attr( 'placeholder' ), 'Basic stuff', 'Attribute: placeholder-msg' ); - } ); - - QUnit.test( 'Proper escaping', 2, function ( assert ) { - var html, $lc; - mw.messages.set( 'properfoo', '<proper esc="test">' ); - - // This is handled by jQuery inside $.fn.localize, just a simple sanity checked - // making sure it is actually using text() and attr() (or something with the same effect) - - // Text escaping - html = '<div><span><html:msg key="properfoo" /></span></div>'; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.text(), mw.msg( 'properfoo' ), 'Content is inserted as text, not as html.' ); - - // Attribute escaping - html = '<div><span title-msg="properfoo"></span></div>'; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), mw.msg( 'properfoo' ), 'Attributes are not inserted raw.' ); - } ); - - QUnit.test( 'Options', 7, function ( assert ) { - mw.messages.set( { - 'foo-lorem': 'Lorem', - 'foo-ipsum': 'Ipsum', - 'foo-bar-title': 'Read more about bars', - 'foo-bar-label': 'The Bars', - 'foo-bazz-title': 'Read more about bazz at $1 (last modified: $2)', - 'foo-bazz-label': 'The Bazz ($1)', - 'foo-welcome': 'Welcome to $1! (last visit: $2)' - } ); - var html, $lc, x, sitename = 'Wikipedia'; - - // Message key prefix - html = '<div><span title-msg="lorem"><html:msg key="ipsum" /></span></div>'; - $lc = $( html ).localize( { - prefix: 'foo-' - } ).find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), 'Lorem', 'Message key prefix - attr' ); - assert.strictEqual( $lc.text(), 'Ipsum', 'Message key prefix - text' ); - - // Variable keys mapping - x = 'bar'; - html = '<div><span title-msg="title"><html:msg key="label" /></span></div>'; - $lc = $( html ).localize( { - keys: { - 'title': 'foo-' + x + '-title', - 'label': 'foo-' + x + '-label' - } - } ).find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), 'Read more about bars', 'Variable keys mapping - attr' ); - assert.strictEqual( $lc.text(), 'The Bars', 'Variable keys mapping - text' ); - - // Passing parameteters to mw.msg - html = '<div><span><html:msg key="foo-welcome" /></span></div>'; - $lc = $( html ).localize( { - params: { - 'foo-welcome': [sitename, 'yesterday'] - } - } ).find( 'span' ); - - assert.strictEqual( $lc.text(), 'Welcome to Wikipedia! (last visit: yesterday)', 'Passing parameteters to mw.msg' ); - - // Combination of options prefix, params and keys - x = 'bazz'; - html = '<div><span title-msg="title"><html:msg key="label" /></span></div>'; - $lc = $( html ).localize( { - prefix: 'foo-', - keys: { - 'title': x + '-title', - 'label': x + '-label' - }, - params: { - 'title': [sitename, '3 minutes ago'], - 'label': [sitename, '3 minutes ago'] - - } - } ).find( 'span' ); - - assert.strictEqual( $lc.text(), 'The Bazz (Wikipedia)', 'Combination of options prefix, params and keys - text' ); - assert.strictEqual( $lc.attr( 'title' ), 'Read more about bazz at Wikipedia (last modified: 3 minutes ago)', 'Combination of options prefix, params and keys - attr' ); - } ); - - QUnit.test( 'Handle data text', 2, function ( assert ) { - var html, $lc; - mw.messages.set( 'option-one', 'Item 1' ); - mw.messages.set( 'option-two', 'Item 2' ); - html = '<select><option data-msg-text="option-one"></option><option data-msg-text="option-two"></option></select>'; - $lc = $( html ).localize().find( 'option' ); - assert.strictEqual( $lc.eq( 0 ).text(), mw.msg( 'option-one' ), 'data-msg-text becomes text of options' ); - assert.strictEqual( $lc.eq( 1 ).text(), mw.msg( 'option-two' ), 'data-msg-text becomes text of options' ); - } ); - - QUnit.test( 'Handle data html', 2, function ( assert ) { - var html, $lc; - mw.messages.set( 'html', 'behold... there is a <a>link</a> here!!' ); - html = '<div><div data-msg-html="html"></div></div>'; - $lc = $( html ).localize().find( 'a' ); - assert.strictEqual( $lc.length, 1, 'link is created' ); - assert.strictEqual( $lc.text(), 'link', 'the link text got added' ); - } ); -}( jQuery, mediaWiki ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js b/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js deleted file mode 100644 index 6da56ed2..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js +++ /dev/null @@ -1,287 +0,0 @@ -( 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( - '<div class="mw-collapsible">' + loremIpsum + '</div>' - ); - $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 (<div>)', 5, function ( assert ) { - var $collapsible, $content, $toggle; - $collapsible = prepareCollapsible( - '<div class="mw-collapsible">' + loremIpsum + '</div>' - ); - $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 (<table>)', 7, function ( assert ) { - var $collapsible, $headerRow, $contentRow, $toggle; - $collapsible = prepareCollapsible( - '<table class="mw-collapsible">' + - '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' + - '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' + - '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' + - '</table>' - ); - $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">' + - '<li>' + loremIpsum + '</li>' + - '<li>' + loremIpsum + '</li>' + - '</' + listType + '>' - ); - $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 (<ul>)', 7, function ( assert ) { - listTest( 'ul', assert ); - } ); - - QUnit.asyncTest( 'basic operation (<ol>)', 7, function ( assert ) { - listTest( 'ol', assert ); - } ); - - QUnit.test( 'basic operation when synchronous (options.instantHide)', 2, function ( assert ) { - var $collapsible, $content; - $collapsible = prepareCollapsible( - '<div class="mw-collapsible">' + loremIpsum + '</div>', - { instantHide: true } - ); - $content = $collapsible.find( '.mw-collapsible-content' ); - - assert.assertTrue( $content.is( ':visible' ), 'content is visible' ); - - $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); - - assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' ); - } ); - - QUnit.test( 'mw-made-collapsible data added', 1, function ( assert ) { - var $collapsible; - $collapsible = prepareCollapsible( - '<div>' + loremIpsum + '</div>' - ); - assert.equal( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' ); - } ); - - QUnit.test( 'mw-collapsible added when missing', 1, function ( assert ) { - var $collapsible; - $collapsible = prepareCollapsible( - '<div>' + loremIpsum + '</div>' - ); - assert.assertTrue( $collapsible.hasClass( 'mw-collapsible' ), 'mw-collapsible class present' ); - } ); - - QUnit.test( 'mw-collapsed added when missing', 1, function ( assert ) { - var $collapsible; - $collapsible = prepareCollapsible( - '<div>' + loremIpsum + '</div>', - { collapsed: true } - ); - assert.assertTrue( $collapsible.hasClass( 'mw-collapsed' ), 'mw-collapsed class present' ); - } ); - - QUnit.asyncTest( 'initial collapse (mw-collapsed class)', 2, function ( assert ) { - var $collapsible, $content; - $collapsible = prepareCollapsible( - '<div class="mw-collapsible mw-collapsed">' + loremIpsum + '</div>' - ); - $content = $collapsible.find( '.mw-collapsible-content' ); - - // Synchronous - mw-collapsed should cause instantHide: true to be used on initial collapsing - assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' ); - - $collapsible.on( 'afterExpand.mw-collapsible', function () { - assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' ); - QUnit.start(); - } ); - - $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); - } ); - - QUnit.asyncTest( 'initial collapse (options.collapsed)', 2, function ( assert ) { - var $collapsible, $content; - $collapsible = prepareCollapsible( - '<div class="mw-collapsible">' + loremIpsum + '</div>', - { collapsed: true } - ); - $content = $collapsible.find( '.mw-collapsible-content' ); - - // Synchronous - collapsed: true should cause instantHide: true to be used on initial collapsing - assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' ); - - $collapsible.on( 'afterExpand.mw-collapsible', function () { - assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' ); - QUnit.start(); - } ); - - $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); - } ); - - QUnit.test( 'clicks on links inside toggler pass through (options.linksPassthru)' , 2, function ( assert ) { - var $collapsible, $content; - - $collapsible = prepareCollapsible( - '<div class="mw-collapsible">' + - '<div class="mw-collapsible-toggle">' + - 'Toggle <a href="#top">toggle</a> toggle <b>toggle</b>' + - '</div>' + - '<div class="mw-collapsible-content">' + loremIpsum + '</div>' + - '</div>', - // Can't do asynchronous because we're testing that the event *doesn't* happen - { instantHide: true } - ); - $content = $collapsible.find( '.mw-collapsible-content' ); - - $collapsible.find( '.mw-collapsible-toggle a' ).trigger( 'click' ); - assert.assertTrue( $content.is( ':visible' ), 'click event on link inside toggle passes through (content not toggled)' ); - - $collapsible.find( '.mw-collapsible-toggle b' ).trigger( 'click' ); - assert.assertTrue( $content.is( ':hidden' ), 'click event on non-link inside toggle toggles content' ); - } ); - - QUnit.asyncTest( 'collapse/expand text (data-collapsetext, data-expandtext)', 2, function ( assert ) { - var $collapsible, $toggleLink; - $collapsible = prepareCollapsible( - '<div class="mw-collapsible" data-collapsetext="Collapse me!" data-expandtext="Expand me!">' + - loremIpsum + - '</div>' - ); - $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' ); - - assert.equal( $toggleLink.text(), 'Collapse me!', 'data-collapsetext is respected' ); - - $collapsible.on( 'afterCollapse.mw-collapsible', function () { - assert.equal( $toggleLink.text(), 'Expand me!', 'data-expandtext is respected' ); - QUnit.start(); - } ); - - $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); - } ); - - QUnit.asyncTest( 'collapse/expand text (options.collapseText, options.expandText)', 2, function ( assert ) { - var $collapsible, $toggleLink; - $collapsible = prepareCollapsible( - '<div class="mw-collapsible">' + loremIpsum + '</div>', - { collapseText: 'Collapse me!', expandText: 'Expand me!' } - ); - $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' ); - - assert.equal( $toggleLink.text(), 'Collapse me!', 'options.collapseText is respected' ); - - $collapsible.on( 'afterCollapse.mw-collapsible', function () { - assert.equal( $toggleLink.text(), 'Expand me!', 'options.expandText is respected' ); - QUnit.start(); - } ); - - $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' ); - } ); - -}( mediaWiki, jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js b/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js deleted file mode 100644 index 7571b929..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js +++ /dev/null @@ -1,57 +0,0 @@ -( function ( $ ) { - QUnit.module( 'jquery.mwExtension', QUnit.newMwEnvironment() ); - - QUnit.test( 'String functions', 7, function ( assert ) { - assert.equal( $.trimLeft( ' foo bar ' ), 'foo bar ', 'trimLeft' ); - assert.equal( $.trimRight( ' foo bar ' ), ' foo bar', 'trimRight' ); - assert.equal( $.ucFirst( 'foo' ), 'Foo', 'ucFirst' ); - - assert.equal( $.escapeRE( '<!-- ([{+mW+}]) $^|?>' ), - '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' ); - assert.equal( $.escapeRE( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ), - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'escapeRE - Leave uppercase alone' ); - assert.equal( $.escapeRE( 'abcdefghijklmnopqrstuvwxyz' ), - 'abcdefghijklmnopqrstuvwxyz', 'escapeRE - Leave lowercase alone' ); - assert.equal( $.escapeRE( '0123456789' ), '0123456789', 'escapeRE - Leave numbers alone' ); - } ); - - QUnit.test( 'Is functions', 15, function ( assert ) { - assert.strictEqual( $.isDomElement( document.getElementById( 'qunit-header' ) ), true, - 'isDomElement: #qunit-header Node' ); - assert.strictEqual( $.isDomElement( document.getElementById( 'random-name' ) ), false, - 'isDomElement: #random-name (null)' ); - assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' ) ), false, - 'isDomElement: getElementsByTagName Array' ); - assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' )[0] ), true, - 'isDomElement: getElementsByTagName(..)[0] Node' ); - assert.strictEqual( $.isDomElement( $( 'div' ) ), false, - 'isDomElement: jQuery object' ); - assert.strictEqual( $.isDomElement( $( 'div' ).get( 0 ) ), true, - 'isDomElement: jQuery object > Get node' ); - assert.strictEqual( $.isDomElement( document.createElement( 'div' ) ), true, - 'isDomElement: createElement' ); - assert.strictEqual( $.isDomElement( { foo: 1 } ), false, - 'isDomElement: Object' ); - - assert.strictEqual( $.isEmpty( 'string' ), false, 'isEmpty: "string"' ); - assert.strictEqual( $.isEmpty( '0' ), true, 'isEmpty: "0"' ); - assert.strictEqual( $.isEmpty( '' ), true, 'isEmpty: ""' ); - assert.strictEqual( $.isEmpty( 1 ), false, 'isEmpty: 1' ); - assert.strictEqual( $.isEmpty( [] ), true, 'isEmpty: []' ); - assert.strictEqual( $.isEmpty( {} ), true, 'isEmpty: {}' ); - - // Documented behavior - assert.strictEqual( $.isEmpty( { length: 0 } ), true, 'isEmpty: { length: 0 }' ); - } ); - - QUnit.test( 'Comparison functions', 5, function ( assert ) { - assert.ok( $.compareArray( [0, 'a', [], [2, 'b'] ], [0, 'a', [], [2, 'b'] ] ), - 'compareArray: Two deep arrays that are excactly the same' ); - assert.ok( !$.compareArray( [1], [2] ), 'compareArray: Two different arrays (false)' ); - - assert.ok( $.compareObject( {}, {} ), 'compareObject: Two empty objects' ); - assert.ok( $.compareObject( { foo: 1 }, { foo: 1 } ), 'compareObject: Two the same objects' ); - assert.ok( !$.compareObject( { bar: true }, { baz: false } ), - 'compareObject: Two different objects (false)' ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js b/tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js deleted file mode 100644 index 12137931..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js +++ /dev/null @@ -1,35 +0,0 @@ -( function ( $ ) { - QUnit.module( 'jquery.tabIndex', QUnit.newMwEnvironment() ); - - QUnit.test( 'firstTabIndex', 2, function ( assert ) { - var html, $testA, $testB; - html = '<form>' + - '<input tabindex="7" />' + - '<input tabindex="9" />' + - '<textarea tabindex="2">Foobar</textarea>' + - '<textarea tabindex="5">Foobar</textarea>' + - '</form>'; - - $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' ); - assert.strictEqual( $testA.firstTabIndex(), 2, 'First tabindex should be 2 within this context.' ); - - $testB = $( '<div>' ); - assert.strictEqual( $testB.firstTabIndex(), null, 'Return null if none available.' ); - } ); - - QUnit.test( 'lastTabIndex', 2, function ( assert ) { - var html, $testA, $testB; - html = '<form>' + - '<input tabindex="7" />' + - '<input tabindex="9" />' + - '<textarea tabindex="2">Foobar</textarea>' + - '<textarea tabindex="5">Foobar</textarea>' + - '</form>'; - - $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' ); - assert.strictEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' ); - - $testB = $( '<div>' ); - assert.strictEqual( $testB.lastTabIndex(), null, 'Return null if none available.' ); - } ); -}( jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js b/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js deleted file mode 100644 index f73fd7bf..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js +++ /dev/null @@ -1,1268 +0,0 @@ -( function ( $, mw ) { - /*jshint onevar: false */ - - var config = { - wgMonthNames: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - wgMonthNamesShort: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - wgDefaultDateFormat: 'dmy', - wgSeparatorTransformTable: ['', ''], - wgDigitTransformTable: ['', ''], - wgContentLanguage: 'en' - }; - - QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment( { config: config } ) ); - - /** - * Create an HTML table from an array of row arrays containing text strings. - * First row will be header row. No fancy rowspan/colspan stuff. - * - * @param {String[]} header - * @param {String[][]} data - * @return jQuery - */ - function tableCreate( header, data ) { - var i, - $table = $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ), - $thead = $table.find( 'thead' ), - $tbody = $table.find( 'tbody' ), - $tr = $( '<tr>' ); - - $.each( header, function ( i, str ) { - var $th = $( '<th>' ); - $th.text( str ).appendTo( $tr ); - } ); - $tr.appendTo( $thead ); - - for ( i = 0; i < data.length; i++ ) { - /*jshint loopfunc: true */ - $tr = $( '<tr>' ); - $.each( data[i], function ( j, str ) { - var $td = $( '<td>' ); - $td.text( str ).appendTo( $tr ); - } ); - $tr.appendTo( $tbody ); - } - return $table; - } - - /** - * Extract text from table. - * - * @param {jQuery} $table - * @return String[][] - */ - function tableExtract( $table ) { - var data = []; - - $table.find( 'tbody' ).find( 'tr' ).each( function ( i, tr ) { - var row = []; - $( tr ).find( 'td,th' ).each( function ( i, td ) { - row.push( $( td ).text() ); - } ); - data.push( row ); - } ); - return data; - } - - /** - * Run a table test by building a table with the given data, - * running some callback on it, then checking the results. - * - * @param {String} msg text to pass on to qunit for the comparison - * @param {String[]} header cols to make the table - * @param {String[][]} data rows/cols to make the table - * @param {String[][]} expected rows/cols to compare against at end - * @param {function($table)} callback something to do with the table before we compare - */ - function tableTest( msg, header, data, expected, callback ) { - QUnit.test( msg, 1, function ( assert ) { - var $table = tableCreate( header, data ); - - // Give caller a chance to set up sorting and manipulate the table. - callback( $table ); - - // Table sorting is done synchronously; if it ever needs to change back - // to asynchronous, we'll need a timeout or a callback here. - var extracted = tableExtract( $table ); - assert.deepEqual( extracted, expected, msg ); - } ); - } - - /** - * Run a table test by building a table with the given HTML, - * running some callback on it, then checking the results. - * - * @param {String} msg text to pass on to qunit for the comparison - * @param {String} HTML to make the table - * @param {String[][]} expected rows/cols to compare against at end - * @param {function($table)} callback something to do with the table before we compare - */ - function tableTestHTML( msg, html, expected, callback ) { - QUnit.test( msg, 1, function ( assert ) { - var $table = $( html ); - - // Give caller a chance to set up sorting and manipulate the table. - if ( callback ) { - callback( $table ); - } else { - $table.tablesorter(); - $table.find( '#sortme' ).click(); - } - - // Table sorting is done synchronously; if it ever needs to change back - // to asynchronous, we'll need a timeout or a callback here. - var extracted = tableExtract( $table ); - assert.deepEqual( extracted, expected, msg ); - } ); - } - - function reversed( arr ) { - // Clone array - var arr2 = arr.slice( 0 ); - - arr2.reverse(); - - return arr2; - } - - // Sample data set using planets named and their radius - var header = [ 'Planet' , 'Radius (km)'], - mercury = [ 'Mercury', '2439.7' ], - venus = [ 'Venus' , '6051.8' ], - earth = [ 'Earth' , '6371.0' ], - mars = [ 'Mars' , '3390.0' ], - jupiter = [ 'Jupiter', '69911' ], - saturn = [ 'Saturn' , '58232' ]; - - // Initial data set - var planets = [mercury, venus, earth, mars, jupiter, saturn]; - var ascendingName = [earth, jupiter, mars, mercury, saturn, venus]; - var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter]; - - tableTest( - 'Basic planet table: sorting initially - ascending by name', - header, - planets, - ascendingName, - function ( $table ) { - $table.tablesorter( { sortList: [ - { 0: 'asc' } - ] } ); - } - ); - tableTest( - 'Basic planet table: sorting initially - descending by radius', - header, - planets, - reversed( ascendingRadius ), - function ( $table ) { - $table.tablesorter( { sortList: [ - { 1: 'desc' } - ] } ); - } - ); - tableTest( - 'Basic planet table: ascending by name', - header, - planets, - ascendingName, - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( - 'Basic planet table: ascending by name a second time', - header, - planets, - ascendingName, - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( - 'Basic planet table: ascending by name (multiple clicks)', - header, - planets, - ascendingName, - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - $table.find( '.headerSort:eq(1)' ).click(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( - 'Basic planet table: descending by name', - header, - planets, - reversed( ascendingName ), - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click().click(); - } - ); - tableTest( - 'Basic planet table: ascending radius', - header, - planets, - ascendingRadius, - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(1)' ).click(); - } - ); - tableTest( - 'Basic planet table: descending radius', - header, - planets, - reversed( ascendingRadius ), - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(1)' ).click().click(); - } - ); - - // Sample data set to test multiple column sorting - header = [ 'column1' , 'column2']; - var - a1 = [ 'A', '1' ], - a2 = [ 'A', '2' ], - a3 = [ 'A', '3' ], - b1 = [ 'B', '1' ], - b2 = [ 'B', '2' ], - b3 = [ 'B', '3' ]; - var initial = [a2, b3, a1, a3, b2, b1]; - var asc = [a1, a2, a3, b1, b2, b3]; - var descasc = [b1, b2, b3, a1, a2, a3]; - - tableTest( - 'Sorting multiple columns by passing sort list', - header, - initial, - asc, - function ( $table ) { - $table.tablesorter( - { sortList: [ - { 0: 'asc' }, - { 1: 'asc' } - ] } - ); - } - ); - tableTest( - 'Sorting multiple columns by programmatically triggering sort()', - header, - initial, - descasc, - function ( $table ) { - $table.tablesorter(); - $table.data( 'tablesorter' ).sort( - [ - { 0: 'desc' }, - { 1: 'asc' } - ] - ); - } - ); - tableTest( - 'Reset to initial sorting by triggering sort() without any parameters', - header, - initial, - asc, - function ( $table ) { - $table.tablesorter( - { sortList: [ - { 0: 'asc' }, - { 1: 'asc' } - ] } - ); - $table.data( 'tablesorter' ).sort( - [ - { 0: 'desc' }, - { 1: 'asc' } - ] - ); - $table.data( 'tablesorter' ).sort(); - } - ); - tableTest( - 'Sort via click event after having initialized the tablesorter with initial sorting', - header, - initial, - descasc, - function ( $table ) { - $table.tablesorter( - { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] } - ); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( - 'Multi-sort via click event after having initialized the tablesorter with initial sorting', - header, - initial, - asc, - function ( $table ) { - $table.tablesorter( - { sortList: [ { 0: 'desc' }, { 1: 'desc' } ] } - ); - $table.find( '.headerSort:eq(0)' ).click(); - - // Pretend to click while pressing the multi-sort key - var event = $.Event( 'click' ); - event[$table.data( 'tablesorter' ).config.sortMultiSortKey] = true; - $table.find( '.headerSort:eq(1)' ).trigger( event ); - } - ); - QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) { - var $table = tableCreate( header, initial ); - $table.tablesorter( - { sortList: [ - { 0: 'desc' }, - { 1: 'asc' } - ] } - ); - $table.data( 'tablesorter' ).sort( [] ); - - assert.equal( - $table.find( 'th.headerSortUp' ).length + $table.find( 'th.headerSortDown' ).length, - 0, - 'No sort specific sort classes addign to header cells' - ); - - assert.equal( - $table.find( 'th' ).first().attr( 'title' ), - mw.msg( 'sort-ascending' ), - 'First header cell has default title' - ); - - assert.equal( - $table.find( 'th' ).first().attr( 'title' ), - $table.find( 'th' ).last().attr( 'title' ), - 'Both header cells\' titles match' - ); - } ); - - // Sorting with colspans - header = [ 'column1a' , 'column1b', 'column1c', 'column2' ]; - var - aaa1 = [ 'A', 'A', 'A', '1' ], - aab5 = [ 'A', 'A', 'B', '5' ], - abc3 = [ 'A', 'B', 'C', '3' ], - bbc2 = [ 'B', 'B', 'C', '2' ], - caa4 = [ 'C', 'A', 'A', '4' ]; - // initial is already declared above - initial = [ aab5, aaa1, abc3, bbc2, caa4 ]; - tableTest( 'Sorting with colspanned headers: spanned column', - header, - initial, - [ aaa1, aab5, abc3, bbc2, caa4 ], - function ( $table ) { - // Make colspanned header for test - $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); - $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( 'Sorting with colspanned headers: sort spanned column twice', - header, - initial, - [ caa4, bbc2, abc3, aab5, aaa1 ], - function ( $table ) { - // Make colspanned header for test - $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); - $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( 'Sorting with colspanned headers: subsequent column', - header, - initial, - [ aaa1, bbc2, abc3, caa4, aab5 ], - function ( $table ) { - // Make colspanned header for test - $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); - $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(1)' ).click(); - } - ); - tableTest( 'Sorting with colspanned headers: sort subsequent column twice', - header, - initial, - [ aab5, caa4, abc3, bbc2, aaa1 ], - function ( $table ) { - // Make colspanned header for test - $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); - $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(1)' ).click(); - $table.find( '.headerSort:eq(1)' ).click(); - } - ); - - - tableTest( - 'Basic planet table: one unsortable column', - header, - planets, - planets, - function ( $table ) { - $table.find( 'tr:eq(0) > th:eq(0)' ).addClass( 'unsortable' ); - - $table.tablesorter(); - $table.find( 'tr:eq(0) > th:eq(0)' ).click(); - } - ); - - // Regression tests! - tableTest( - 'Bug 28775: German-style (dmy) short numeric dates', - ['Date'], - [ - // German-style dates are day-month-year - ['11.11.2011'], - ['01.11.2011'], - ['02.10.2011'], - ['03.08.2011'], - ['09.11.2011'] - ], - [ - // Sorted by ascending date - ['03.08.2011'], - ['02.10.2011'], - ['01.11.2011'], - ['09.11.2011'], - ['11.11.2011'] - ], - function ( $table ) { - mw.config.set( 'wgDefaultDateFormat', 'dmy' ); - mw.config.set( 'wgContentLanguage', 'de' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - tableTest( - 'Bug 28775: American-style (mdy) short numeric dates', - ['Date'], - [ - // American-style dates are month-day-year - ['11.11.2011'], - ['01.11.2011'], - ['02.10.2011'], - ['03.08.2011'], - ['09.11.2011'] - ], - [ - // Sorted by ascending date - ['01.11.2011'], - ['02.10.2011'], - ['03.08.2011'], - ['09.11.2011'], - ['11.11.2011'] - ], - function ( $table ) { - mw.config.set( 'wgDefaultDateFormat', 'mdy' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - var ipv4 = [ - // Some randomly generated fake IPs - ['45.238.27.109'], - ['44.172.9.22'], - ['247.240.82.209'], - ['204.204.132.158'], - ['170.38.91.162'], - ['197.219.164.9'], - ['45.68.154.72'], - ['182.195.149.80'] - ]; - var ipv4Sorted = [ - // Sort order should go octet by octet - ['44.172.9.22'], - ['45.68.154.72'], - ['45.238.27.109'], - ['170.38.91.162'], - ['182.195.149.80'], - ['197.219.164.9'], - ['204.204.132.158'], - ['247.240.82.209'] - ]; - - tableTest( - 'Bug 17141: IPv4 address sorting', - ['IP'], - ipv4, - ipv4Sorted, - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( - 'Bug 17141: IPv4 address sorting (reverse)', - ['IP'], - ipv4, - reversed( ipv4Sorted ), - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click().click(); - } - ); - - var umlautWords = [ - // Some words with Umlauts - ['Günther'], - ['Peter'], - ['Björn'], - ['Bjorn'], - ['Apfel'], - ['Äpfel'], - ['Strasse'], - ['Sträßschen'] - ]; - - var umlautWordsSorted = [ - // Some words with Umlauts - ['Äpfel'], - ['Apfel'], - ['Björn'], - ['Bjorn'], - ['Günther'], - ['Peter'], - ['Sträßschen'], - ['Strasse'] - ]; - - tableTest( - 'Accented Characters with custom collation', - ['Name'], - umlautWords, - umlautWordsSorted, - function ( $table ) { - mw.config.set( 'tableSorterCollation', { - 'ä': 'ae', - 'ö': 'oe', - 'ß': 'ss', - 'ü': 'ue' - } ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - QUnit.test( 'Rowspan not exploded on init', 1, function ( assert ) { - var $table = tableCreate( header, planets ); - - // Modify the table to have a multiple-row-spanning cell: - // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row. - $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); - // - Set rowspan for 2nd cell of 3rd row to 3. - // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); - - $table.tablesorter(); - - assert.equal( - $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowSpan' ), - 3, - 'Rowspan not exploded' - ); - } ); - - var planetsRowspan = [ - [ 'Earth', '6051.8' ], - jupiter, - [ 'Mars', '6051.8' ], - mercury, - saturn, - venus - ]; - var planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ]; - - tableTest( - 'Basic planet table: same value for multiple rows via rowspan', - header, - planets, - planetsRowspan, - function ( $table ) { - // Modify the table to have a multiple-row-spanning cell: - // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row. - $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); - // - Set rowspan for 2nd cell of 3rd row to 3. - // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - tableTest( - 'Basic planet table: same value for multiple rows via rowspan (sorting initially)', - header, - planets, - planetsRowspan, - function ( $table ) { - // Modify the table to have a multiple-row-spanning cell: - // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row. - $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); - // - Set rowspan for 2nd cell of 3rd row to 3. - // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); - - $table.tablesorter( { sortList: [ - { 0: 'asc' } - ] } ); - } - ); - tableTest( - 'Basic planet table: Same value for multiple rows via rowspan II', - header, - planets, - planetsRowspanII, - function ( $table ) { - // Modify the table to have a multiple-row-spanning cell: - // - Remove 1st cell of 4th row, and, 1st cell or 5th row. - $table.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove(); - // - Set rowspan for 1st cell of 3rd row to 3. - // This covers the removed cell in the 4th and 5th row. - $table.find( 'tr:eq(2) td:eq(0)' ).attr( 'rowspan', '3' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - var complexMDYDates = [ - // Some words with Umlauts - ['January, 19 2010'], - ['April 21 1991'], - ['04 22 1991'], - ['5.12.1990'], - ['December 12 \'10'] - ]; - - var complexMDYSorted = [ - ['5.12.1990'], - ['April 21 1991'], - ['04 22 1991'], - ['January, 19 2010'], - ['December 12 \'10'] - ]; - - tableTest( - 'Complex date parsing I', - ['date'], - complexMDYDates, - complexMDYSorted, - function ( $table ) { - mw.config.set( 'wgDefaultDateFormat', 'mdy' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - var currencyUnsorted = [ - ['1.02 $'], - ['$ 3.00'], - ['€ 2,99'], - ['$ 1.00'], - ['$3.50'], - ['$ 1.50'], - ['€ 0.99'] - ]; - - var currencySorted = [ - ['€ 0.99'], - ['$ 1.00'], - ['1.02 $'], - ['$ 1.50'], - ['$ 3.00'], - ['$3.50'], - // Comma's sort after dots - // Not intentional but test to detect changes - ['€ 2,99'] - ]; - - tableTest( - 'Currency parsing I', - ['currency'], - currencyUnsorted, - currencySorted, - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - var ascendingNameLegacy = ascendingName.slice( 0 ); - ascendingNameLegacy[4] = ascendingNameLegacy[5]; - ascendingNameLegacy.pop(); - - tableTest( - 'Legacy compat with .sortbottom', - header, - planets, - ascendingNameLegacy, - function ( $table ) { - $table.find( 'tr:last' ).addClass( 'sortbottom' ); - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - QUnit.test( 'Test detection routine', 1, function ( assert ) { - var $table; - $table = $( - '<table class="sortable">' + - '<caption>CAPTION</caption>' + - '<tr><th>THEAD</th></tr>' + - '<tr><td>1</td></tr>' + - '<tr class="sortbottom"><td>text</td></tr>' + - '</table>' - ); - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - - assert.equal( - $table.data( 'tablesorter' ).config.parsers[0].id, - 'number', - 'Correctly detected column content skipping sortbottom' - ); - } ); - - /** FIXME: the diff output is not very readeable. */ - QUnit.test( 'bug 32047 - caption must be before thead', 1, function ( assert ) { - var $table; - $table = $( - '<table class="sortable">' + - '<caption>CAPTION</caption>' + - '<tr><th>THEAD</th></tr>' + - '<tr><td>A</td></tr>' + - '<tr><td>B</td></tr>' + - '<tr class="sortbottom"><td>TFOOT</td></tr>' + - '</table>' - ); - $table.tablesorter(); - - assert.equal( - $table.children().get( 0 ).nodeName, - 'CAPTION', - 'First element after <thead> must be <caption> (bug 32047)' - ); - } ); - - QUnit.test( 'data-sort-value attribute, when available, should override sorting position', 3, function ( assert ) { - var $table, data; - - // Example 1: All cells except one cell without data-sort-value, - // which should be sorted at it's text content value. - $table = $( - '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' + - '<tbody>' + - '<tr><td>Cheetah</td></tr>' + - '<tr><td data-sort-value="Apple">Bird</td></tr>' + - '<tr><td data-sort-value="Bananna">Ferret</td></tr>' + - '<tr><td data-sort-value="Drupe">Elephant</td></tr>' + - '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' + - '</tbody></table>' - ); - $table.tablesorter().find( '.headerSort:eq(0)' ).click(); - - data = []; - $table.find( 'tbody > tr' ).each( function ( i, tr ) { - $( tr ).find( 'td' ).each( function ( i, td ) { - data.push( { - data: $( td ).data( 'sortValue' ), - text: $( td ).text() - } ); - } ); - } ); - - assert.deepEqual( data, [ - { - data: 'Apple', - text: 'Bird' - }, - { - data: 'Bananna', - text: 'Ferret' - }, - { - data: undefined, - text: 'Cheetah' - }, - { - data: 'Cherry', - text: 'Dolphin' - }, - { - data: 'Drupe', - text: 'Elephant' - } - ], 'Order matches expected order (based on data-sort-value attribute values)' ); - - // Example 2 - $table = $( - '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' + - '<tbody>' + - '<tr><td>D</td></tr>' + - '<tr><td data-sort-value="E">A</td></tr>' + - '<tr><td>B</td></tr>' + - '<tr><td>G</td></tr>' + - '<tr><td data-sort-value="F">C</td></tr>' + - '</tbody></table>' - ); - $table.tablesorter().find( '.headerSort:eq(0)' ).click(); - - data = []; - $table.find( 'tbody > tr' ).each( function ( i, tr ) { - $( tr ).find( 'td' ).each( function ( i, td ) { - data.push( { - data: $( td ).data( 'sortValue' ), - text: $( td ).text() - } ); - } ); - } ); - - assert.deepEqual( data, [ - { - data: undefined, - text: 'B' - }, - { - data: undefined, - text: 'D' - }, - { - data: 'E', - text: 'A' - }, - { - data: 'F', - text: 'C' - }, - { - data: undefined, - text: 'G' - } - ], 'Order matches expected order (based on data-sort-value attribute values)' ); - - // Example 3: Test that live changes are used from data-sort-value, - // even if they change after the tablesorter is constructed (bug 38152). - $table = $( - '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' + - '<tbody>' + - '<tr><td>D</td></tr>' + - '<tr><td data-sort-value="1">A</td></tr>' + - '<tr><td>B</td></tr>' + - '<tr><td data-sort-value="2">G</td></tr>' + - '<tr><td>C</td></tr>' + - '</tbody></table>' - ); - // initialize table sorter and sort once - $table - .tablesorter() - .find( '.headerSort:eq(0)' ).click(); - - // Change the sortValue data properties (bug 38152) - // - change data - $table.find( 'td:contains(A)' ).data( 'sortValue', 3 ); - // - add data - $table.find( 'td:contains(B)' ).data( 'sortValue', 1 ); - // - remove data, bring back attribute: 2 - $table.find( 'td:contains(G)' ).removeData( 'sortValue' ); - - // Now sort again (twice, so it is back at Ascending) - $table.find( '.headerSort:eq(0)' ).click(); - $table.find( '.headerSort:eq(0)' ).click(); - - data = []; - $table.find( 'tbody > tr' ).each( function ( i, tr ) { - $( tr ).find( 'td' ).each( function ( i, td ) { - data.push( { - data: $( td ).data( 'sortValue' ), - text: $( td ).text() - } ); - } ); - } ); - - assert.deepEqual( data, [ - { - data: 1, - text: 'B' - }, - { - data: 2, - text: 'G' - }, - { - data: 3, - text: 'A' - }, - { - data: undefined, - text: 'C' - }, - { - data: undefined, - text: 'D' - } - ], 'Order matches expected order, using the current sortValue in $.data()' ); - - } ); - - var numbers = [ - [ '12' ], - [ '7' ], - [ '13,000'], - [ '9' ], - [ '14' ], - [ '8.0' ] - ]; - var numbersAsc = [ - [ '7' ], - [ '8.0' ], - [ '9' ], - [ '12' ], - [ '14' ], - [ '13,000'] - ]; - - tableTest( 'bug 8115: sort numbers with commas (ascending)', - ['Numbers'], numbers, numbersAsc, - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - tableTest( 'bug 8115: sort numbers with commas (descending)', - ['Numbers'], numbers, reversed( numbersAsc ), - function ( $table ) { - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click().click(); - } - ); - // TODO add numbers sorting tests for bug 8115 with a different language - - QUnit.test( 'bug 32888 - Tables inside a tableheader cell', 2, function ( assert ) { - var $table; - $table = $( - '<table class="sortable" id="mw-bug-32888">' + - '<tr><th>header<table id="mw-bug-32888-2">' + - '<tr><th>1</th><th>2</th></tr>' + - '</table></th></tr>' + - '<tr><td>A</td></tr>' + - '<tr><td>B</td></tr>' + - '</table>' - ); - $table.tablesorter(); - - assert.equal( - $table.find( '> thead:eq(0) > tr > th.headerSort' ).length, - 1, - 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)' - ); - assert.equal( - $( '#mw-bug-32888-2' ).find( 'th.headerSort' ).length, - 0, - 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)' - ); - } ); - - - var correctDateSorting1 = [ - ['01 January 2010'], - ['05 February 2010'], - ['16 January 2010'] - ]; - - var correctDateSortingSorted1 = [ - ['01 January 2010'], - ['16 January 2010'], - ['05 February 2010'] - ]; - - tableTest( - 'Correct date sorting I', - ['date'], - correctDateSorting1, - correctDateSortingSorted1, - function ( $table ) { - mw.config.set( 'wgDefaultDateFormat', 'mdy' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - var correctDateSorting2 = [ - ['January 01 2010'], - ['February 05 2010'], - ['January 16 2010'] - ]; - - var correctDateSortingSorted2 = [ - ['January 01 2010'], - ['January 16 2010'], - ['February 05 2010'] - ]; - - tableTest( - 'Correct date sorting II', - ['date'], - correctDateSorting2, - correctDateSortingSorted2, - function ( $table ) { - mw.config.set( 'wgDefaultDateFormat', 'dmy' ); - - $table.tablesorter(); - $table.find( '.headerSort:eq(0)' ).click(); - } - ); - - QUnit.test( 'Sorting images using alt text', 1, function ( assert ) { - var $table = $( - '<table class="sortable">' + - '<tr><th>THEAD</th></tr>' + - '<tr><td><img alt="2"/></td></tr>' + - '<tr><td>1</td></tr>' + - '</table>' - ); - $table.tablesorter().find( '.headerSort:eq(0)' ).click(); - - assert.equal( - $table.find( 'td' ).first().text(), - '1', - 'Applied correct sorting order' - ); - } ); - - QUnit.test( 'Sorting images using alt text (complex)', 1, function ( assert ) { - var $table = $( - '<table class="sortable">' + - '<tr><th>THEAD</th></tr>' + - '<tr><td><img alt="D" />A</td></tr>' + - '<tr><td>CC</td></tr>' + - '<tr><td><a><img alt="A" /></a>F</tr>' + - '<tr><td><img alt="A" /><strong>E</strong></tr>' + - '<tr><td><strong><img alt="A" />D</strong></tr>' + - '<tr><td><img alt="A" />C</tr>' + - '</table>' - ); - $table.tablesorter().find( '.headerSort:eq(0)' ).click(); - - assert.equal( - $table.find( 'td' ).text(), - 'CDEFCCA', - 'Applied correct sorting order' - ); - } ); - - QUnit.test( 'Sorting images using alt text (with format autodetection)', 1, function ( assert ) { - var $table = $( - '<table class="sortable">' + - '<tr><th>THEAD</th></tr>' + - '<tr><td><img alt="1" />7</td></tr>' + - '<tr><td>1<img alt="6" /></td></tr>' + - '<tr><td>5</td></tr>' + - '<tr><td>4</td></tr>' + - '</table>' - ); - $table.tablesorter().find( '.headerSort:eq(0)' ).click(); - - assert.equal( - $table.find( 'td' ).text(), - '4517', - 'Applied correct sorting order' - ); - } ); - - QUnit.test( 'bug 38911 - The row with the largest amount of columns should receive the sort indicators', 3, function ( assert ) { - var $table = $( - '<table class="sortable">' + - '<thead>' + - '<tr><th rowspan="2" id="A1">A1</th><th colspan="2">B2a</th></tr>' + - '<tr><th id="B2b">B2b</th><th id="C2b">C2b</th></tr>' + - '</thead>' + - '<tr><td>A</td><td>Aa</td><td>Ab</td></tr>' + - '<tr><td>B</td><td>Ba</td><td>Bb</td></tr>' + - '</table>' - ); - $table.tablesorter(); - - assert.equal( - $table.find( '#A1' ).attr( 'class' ), - 'headerSort', - 'The first column of the first row should be sortable' - ); - assert.equal( - $table.find( '#B2b' ).attr( 'class' ), - 'headerSort', - 'The th element of the 2nd row of the 2nd column should be sortable' - ); - assert.equal( - $table.find( '#C2b' ).attr( 'class' ), - 'headerSort', - 'The th element of the 2nd row of the 3rd column should be sortable' - ); - } ); - - QUnit.test( 'rowspans in table headers should prefer the last row when rows are equal in length', 2, function ( assert ) { - var $table = $( - '<table class="sortable">' + - '<thead>' + - '<tr><th rowspan="2" id="A1">A1</th><th>B2a</th></tr>' + - '<tr><th id="B2b">B2b</th></tr>' + - '</thead>' + - '<tr><td>A</td><td>Aa</td></tr>' + - '<tr><td>B</td><td>Ba</td></tr>' + - '</table>' - ); - $table.tablesorter(); - - assert.equal( - $table.find( '#A1' ).attr( 'class' ), - 'headerSort', - 'The first column of the first row should be sortable' - ); - assert.equal( - $table.find( '#B2b' ).attr( 'class' ), - 'headerSort', - 'The th element of the 2nd row of the 2nd column should be sortable' - ); - } ); - - // bug 41889 - exploding rowspans in more complex cases - tableTestHTML( - 'Rowspan exploding with row headers', - '<table class="sortable">' + - '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th></tr></thead>' + - '<tbody>' + - '<tr><td>1</td><th rowspan="2">foo</th><td rowspan="2">bar</td><td>baz</td></tr>' + - '<tr><td>2</td><td>baz</td></tr>' + - '</tbody></table>', - [ - [ '1', 'foo', 'bar', 'baz' ], - [ '2', 'foo', 'bar', 'baz' ] - ] - ); - - tableTestHTML( - 'Rowspan exploding with colspanned cells', - '<table class="sortable">' + - '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th></tr></thead>' + - '<tbody>' + - '<tr><td>1</td><td>foo</td><td>bar</td><td rowspan="2">baz</td></tr>' + - '<tr><td>2</td><td colspan="2">foobar</td></tr>' + - '</tbody></table>', - [ - [ '1', 'foo', 'bar', 'baz' ], - [ '2', 'foobar', 'baz' ] - ] - ); - - tableTestHTML( - 'Rowspan exploding with colspanned cells (2)', - '<table class="sortable">' + - '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th><th>quux</th></tr></thead>' + - '<tbody>' + - '<tr><td>1</td><td>foo</td><td>bar</td><td rowspan="2">baz</td><td>quux</td></tr>' + - '<tr><td>2</td><td colspan="2">foobar</td><td>quux</td></tr>' + - '</tbody></table>', - [ - [ '1', 'foo', 'bar', 'baz', 'quux' ], - [ '2', 'foobar', 'baz', 'quux' ] - ] - ); - - tableTestHTML( - 'Rowspan exploding with rightmost rows spanning most', - '<table class="sortable">' + - '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th></tr></thead>' + - '<tbody>' + - '<tr><td>1</td><td rowspan="2">foo</td><td rowspan="4">bar</td></tr>' + - '<tr><td>2</td></tr>' + - '<tr><td>3</td><td rowspan="2">foo</td></tr>' + - '<tr><td>4</td></tr>' + - '</tbody></table>', - [ - [ '1', 'foo', 'bar' ], - [ '2', 'foo', 'bar' ], - [ '3', 'foo', 'bar' ], - [ '4', 'foo', 'bar' ] - ] - ); - - tableTestHTML( - 'Rowspan exploding with rightmost rows spanning most (2)', - '<table class="sortable">' + - '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th></tr></thead>' + - '<tbody>' + - '<tr><td>1</td><td rowspan="2">foo</td><td rowspan="4">bar</td><td>baz</td></tr>' + - '<tr><td>2</td><td>baz</td></tr>' + - '<tr><td>3</td><td rowspan="2">foo</td><td>baz</td></tr>' + - '<tr><td>4</td><td>baz</td></tr>' + - '</tbody></table>', - [ - [ '1', 'foo', 'bar', 'baz' ], - [ '2', 'foo', 'bar', 'baz' ], - [ '3', 'foo', 'bar', 'baz' ], - [ '4', 'foo', 'bar', 'baz' ] - ] - ); - - tableTestHTML( - 'Rowspan exploding with row-and-colspanned cells', - '<table class="sortable">' + - '<thead><tr><th id="sortme">n</th><th>foo1</th><th>foo2</th><th>bar</th><th>baz</th></tr></thead>' + - '<tbody>' + - '<tr><td>1</td><td rowspan="2">foo1</td><td rowspan="2">foo2</td><td rowspan="4">bar</td><td>baz</td></tr>' + - '<tr><td>2</td><td>baz</td></tr>' + - '<tr><td>3</td><td colspan="2" rowspan="2">foo</td><td>baz</td></tr>' + - '<tr><td>4</td><td>baz</td></tr>' + - '</tbody></table>', - [ - [ '1', 'foo1', 'foo2', 'bar', 'baz' ], - [ '2', 'foo1', 'foo2', 'bar', 'baz' ], - [ '3', 'foo', 'bar', 'baz' ], - [ '4', 'foo', 'bar', 'baz' ] - ] - ); - - tableTestHTML( - 'Rowspan exploding with uneven rowspan layout', - '<table class="sortable">' + - '<thead><tr><th id="sortme">n</th><th>foo1</th><th>foo2</th><th>foo3</th><th>bar</th><th>baz</th></tr></thead>' + - '<tbody>' + - '<tr><td>1</td><td rowspan="2">foo1</td><td rowspan="2">foo2</td><td rowspan="2">foo3</td><td>bar</td><td>baz</td></tr>' + - '<tr><td>2</td><td rowspan="3">bar</td><td>baz</td></tr>' + - '<tr><td>3</td><td rowspan="2">foo1</td><td rowspan="2">foo2</td><td rowspan="2">foo3</td><td>baz</td></tr>' + - '<tr><td>4</td><td>baz</td></tr>' + - '</tbody></table>', - [ - [ '1', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ], - [ '2', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ], - [ '3', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ], - [ '4', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ] - ] - ); - -}( jQuery, mediaWiki ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js b/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js deleted file mode 100644 index 5fe23944..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js +++ /dev/null @@ -1,275 +0,0 @@ -( function ( $ ) { - - QUnit.module( 'jquery.textSelection', QUnit.newMwEnvironment() ); - - /** - * Test factory for $.fn.textSelection( 'encapsulateText' ) - * - * @param options {object} associative array containing: - * description {string} - * input {string} - * output {string} - * start {int} starting char for selection - * end {int} ending char for selection - * params {object} add'l parameters for $().textSelection( 'encapsulateText' ) - */ - function encapsulateTest( options ) { - var opt = $.extend( { - description: '', - before: {}, - after: {}, - replace: {} - }, options ); - - opt.before = $.extend( { - text: '', - start: 0, - end: 0 - }, opt.before ); - opt.after = $.extend( { - text: '', - selected: null - }, opt.after ); - - QUnit.test( opt.description, function ( assert ) { - /*jshint onevar: false */ - var tests = 1; - if ( opt.after.selected !== null ) { - tests++; - } - QUnit.expect( tests ); - - var $textarea = $( '<textarea>' ); - - $( '#qunit-fixture' ).append( $textarea ); - - //$textarea.textSelection( 'setContents', opt.before.text); // this method is actually missing atm... - $textarea.val( opt.before.text ); // won't work with the WikiEditor iframe? - - var start = opt.before.start, - end = opt.before.end; - - var options = $.extend( {}, opt.replace ); // Clone opt.replace - options.selectionStart = start; - options.selectionEnd = end; - $textarea.textSelection( 'encapsulateSelection', options ); - - var text = $textarea.textSelection( 'getContents' ).replace( /\r\n/g, '\n' ); - - assert.equal( text, opt.after.text, 'Checking full text after encapsulation' ); - - if ( opt.after.selected !== null ) { - var selected = $textarea.textSelection( 'getSelection' ); - assert.equal( selected, opt.after.selected, 'Checking selected text after encapsulation.' ); - } - - } ); - } - - var caretSample, - sig = { - pre: '--~~~~' - }, - bold = { - pre: '\'\'\'', - peri: 'Bold text', - post: '\'\'\'' - }, - h2 = { - pre: '== ', - peri: 'Heading 2', - post: ' ==', - regex: /^(\s*)(={1,6})(.*?)\2(\s*)$/, - regexReplace: '$1==$3==$4', - ownline: true - }, - ulist = { - pre: '* ', - peri: 'Bulleted list item', - post: '', - ownline: true, - splitlines: true - }; - - encapsulateTest( { - description: 'Adding sig to end of text', - before: { - text: 'Wikilove dude! ', - start: 15, - end: 15 - }, - after: { - text: 'Wikilove dude! --~~~~', - selected: '' - }, - replace: sig - } ); - - encapsulateTest( { - description: 'Adding bold to empty', - before: { - text: '', - start: 0, - end: 0 - }, - after: { - text: '\'\'\'Bold text\'\'\'', - selected: 'Bold text' // selected because it's the default - }, - replace: bold - } ); - - encapsulateTest( { - description: 'Adding bold to existing text', - before: { - text: 'Now is the time for all good men to come to the aid of their country', - start: 20, - end: 32 - }, - after: { - text: 'Now is the time for \'\'\'all good men\'\'\' to come to the aid of their country', - selected: '' // empty because it's not the default' - }, - replace: bold - } ); - - encapsulateTest( { - description: 'ownline option: adding new h2', - before: { - text: 'Before\nAfter', - start: 7, - end: 7 - }, - after: { - text: 'Before\n== Heading 2 ==\nAfter', - selected: 'Heading 2' - }, - replace: h2 - } ); - - encapsulateTest( { - description: 'ownline option: turn a whole line into new h2', - before: { - text: 'Before\nMy heading\nAfter', - start: 7, - end: 17 - }, - after: { - text: 'Before\n== My heading ==\nAfter', - selected: '' - }, - replace: h2 - } ); - - - encapsulateTest( { - description: 'ownline option: turn a partial line into new h2', - before: { - text: 'BeforeMy headingAfter', - start: 6, - end: 16 - }, - after: { - text: 'Before\n== My heading ==\nAfter', - selected: '' - }, - replace: h2 - } ); - - - encapsulateTest( { - description: 'splitlines option: no selection, insert new list item', - before: { - text: 'Before\nAfter', - start: 7, - end: 7 - }, - after: { - text: 'Before\n* Bulleted list item\nAfter' - }, - replace: ulist - } ); - - encapsulateTest( { - description: 'splitlines option: single partial line selection, insert new list item', - before: { - text: 'BeforeMy List ItemAfter', - start: 6, - end: 18 - }, - after: { - text: 'Before\n* My List Item\nAfter' - }, - replace: ulist - } ); - - encapsulateTest( { - description: 'splitlines option: multiple lines', - before: { - text: 'Before\nFirst\nSecond\nThird\nAfter', - start: 7, - end: 25 - }, - after: { - text: 'Before\n* First\n* Second\n* Third\nAfter' - }, - replace: ulist - } ); - - - function caretTest( options ) { - QUnit.test( options.description, 2, function ( assert ) { - var pos, $textarea = $( '<textarea>' ).text( options.text ); - - $( '#qunit-fixture' ).append( $textarea ); - - if ( options.mode === 'set' ) { - $textarea.textSelection( 'setSelection', { - start: options.start, - end: options.end - } ); - } - - function among( actual, expected, message ) { - if ( $.isArray( expected ) ) { - assert.ok( $.inArray( actual, expected ) !== -1, message + ' (got ' + actual + '; expected one of ' + expected.join( ', ' ) + ')' ); - } else { - assert.equal( actual, expected, message ); - } - } - - pos = $textarea.textSelection( 'getCaretPosition', { startAndEnd: true } ); - among( pos[0], options.start, 'Caret start should be where we set it.' ); - among( pos[1], options.end, 'Caret end should be where we set it.' ); - } ); - } - - caretSample = 'Some big text that we like to work with. Nothing fancy... you know what I mean?'; - - /* - // @broken: Disabled per bug 34820 - caretTest({ - description: 'getCaretPosition with original/empty selection - bug 31847 with IE 6/7/8', - text: caretSample, - start: [0, caretSample.length], // Opera and Firefox (prior to FF 6.0) default caret to the end of the box (caretSample.length) - end: [0, caretSample.length], // Other browsers default it to the beginning (0), so check both. - mode: 'get' - }); - */ - - caretTest( { - description: 'set/getCaretPosition with forced empty selection', - text: caretSample, - start: 7, - end: 7, - mode: 'set' - } ); - - caretTest( { - description: 'set/getCaretPosition with small selection', - text: caretSample, - start: 6, - end: 11, - mode: 'set' - } ); -}( jQuery ) ); |