diff options
Diffstat (limited to 'tests/qunit/suites/resources/jquery')
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js) | 13 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.byteLength.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.byteLength.js) | 4 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.byteLimit.js) | 136 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.client.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.client.js) | 164 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.colorUtil.js) | 2 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js | 4 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.getAttrs.js) | 2 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.highlightText.test.js | 239 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.localize.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.localize.js) | 2 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js) | 6 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js (renamed from tests/qunit/suites/resources/jquery/jquery.tabIndex.js) | 12 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js | 227 | ||||
-rw-r--r-- | tests/qunit/suites/resources/jquery/jquery.textSelection.test.js | 279 |
13 files changed, 907 insertions, 183 deletions
diff --git a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js b/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js index caf5a6f1..6e371384 100644 --- a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.js +++ b/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js @@ -1,4 +1,4 @@ -module( 'jquery.autoEllipsis.js' ); +module( 'jquery.autoEllipsis', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(1); @@ -6,8 +6,8 @@ test( '-- Initial check', function() { }); function createWrappedDiv( text, width ) { - var $wrapper = $( '<div />' ).css( 'width', width ); - var $div = $( '<div />' ).text( text ); + var $wrapper = $( '<div>' ).css( 'width', width ); + var $div = $( '<div>' ).text( text ); $wrapper.append( $div ); return $wrapper; } @@ -26,7 +26,7 @@ test( 'Position right', function() { // We need this thing to be visible, so append it to the DOM var origText = 'This is a really long random string and there is no way it fits in 100 pixels.'; var $wrapper = createWrappedDiv( origText, '100px' ); - $( 'body' ).append( $wrapper ); + $( '#qunit-fixture' ).append( $wrapper ); $wrapper.autoEllipsis( { position: 'right' } ); // Verify that, and only one, span element was created @@ -47,12 +47,9 @@ test( 'Position right', function() { // 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 ) { + if ( $.browser.msie && Number( $.browser.version ) === 6 ) { 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 { gt( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more)' ); } - - // Clean up - $wrapper.remove(); }); diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLength.js b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js index f82fda27..15fac691 100644 --- a/tests/qunit/suites/resources/jquery/jquery.byteLength.js +++ b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js @@ -1,4 +1,4 @@ -module( 'jquery.byteLength.js' ); +module( 'jquery.byteLength', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(1); @@ -25,7 +25,7 @@ test( 'Simple text', function() { test( 'Special text', window.foo = function() { expect(5); - // http://en.wikipedia.org/wiki/UTF-8 + // http://en.wikipedia.org/wiki/UTF-8 var U_0024 = '\u0024', U_00A2 = '\u00A2', U_20AC = '\u20AC', diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLimit.js b/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js index 461ea49b..3346c2d5 100644 --- a/tests/qunit/suites/resources/jquery/jquery.byteLimit.js +++ b/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js @@ -1,4 +1,6 @@ -module( 'jquery.byteLimit.js' ); +( function () { + +module( 'jquery.byteLimit', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(1); @@ -23,46 +25,47 @@ $.addChars = function( $input, charstr ) { } } }; -var blti = 0; + /** * Test factory for $.fn.byteLimit * * @param $input {jQuery} jQuery object in an input element - * @param useLimit {Boolean} Wether a limit should apply at all + * @param hasLimit {Boolean} Wether a limit should apply at all * @param limit {Number} Limit (if used) otherwise undefined - * The limit should be less than 20 (the sample data's length) + * The limit should be less than 20 (the sample data's length) */ var byteLimitTest = function( options ) { var opt = $.extend({ description: '', $input: null, sample: '', - useLimit: false, - expected: 0, + hasLimit: false, + expected: '', limit: null }, options); - var i = blti++; test( opt.description, function() { - opt.$input.appendTo( 'body' ); - + opt.$input.appendTo( '#qunit-fixture' ); + // Simulate pressing keys for each of the sample characters $.addChars( opt.$input, opt.sample ); - var newVal = opt.$input.val(); - - if ( opt.useLimit ) { - expect(2); - + var rawVal = opt.$input.val(), + fn = opt.$input.data( 'byteLimit-callback' ), + newVal = $.isFunction( fn ) ? fn( rawVal ) : rawVal; + + if ( opt.hasLimit ) { + expect(3); + ltOrEq( $.byteLength( newVal ), opt.limit, 'Prevent keypresses after byteLimit was reached, length never exceeded the limit' ); - equal( $.byteLength( newVal ), opt.expected, 'Not preventing keypresses too early, length has reached the expected length' ); - + equal( $.byteLength( rawVal ), $.byteLength( opt.expected ), 'Not preventing keypresses too early, length has reached the expected length' ); + equal( rawVal, opt.expected, 'New value matches the expected string' ); + } else { - expect(1); - equal( $.byteLength( newVal ), opt.expected, 'Unlimited scenarios are not affected, expected length reached' ); + expect(2); + equal( newVal, opt.expected, 'New value matches the expected string' ); + equal( $.byteLength( newVal ), $.byteLength( opt.expected ), 'Unlimited scenarios are not affected, expected length reached' ); } - - opt.$input.remove(); } ); }; @@ -79,77 +82,106 @@ var byteLimitTest({ description: 'Plain text input', $input: $( '<input>' ) - .attr( { - 'type': 'text' - }), + .attr( 'type', 'text' ), sample: simpleSample, - useLimit: false, - expected: $.byteLength( simpleSample ) + hasLimit: false, + expected: simpleSample }); byteLimitTest({ description: 'Limit using the maxlength attribute', $input: $( '<input>' ) - .attr( { - 'type': 'text', - 'maxlength': '10' - }) + .attr( 'type', 'text' ) + .prop( 'maxLength', '10' ) .byteLimit(), sample: simpleSample, - useLimit: true, + hasLimit: true, limit: 10, - expected: 10 + expected: '1234567890' }); byteLimitTest({ description: 'Limit using a custom value', $input: $( '<input>' ) - .attr( { - 'type': 'text' - }) + .attr( 'type', 'text' ) .byteLimit( 10 ), sample: simpleSample, - useLimit: true, + hasLimit: true, limit: 10, - expected: 10 + expected: '1234567890' }); byteLimitTest({ description: 'Limit using a custom value, overriding maxlength attribute', $input: $( '<input>' ) - .attr( { - 'type': 'text', - 'maxLength': '10' - }) + .attr( 'type', 'text' ) + .prop( 'maxLength', '10' ) .byteLimit( 15 ), sample: simpleSample, - useLimit: true, + hasLimit: true, limit: 15, - expected: 15 + expected: '123456789012345' }); byteLimitTest({ description: 'Limit using a custom value (multibyte)', $input: $( '<input>' ) - .attr( { - 'type': 'text' - }) + .attr( 'type', 'text' ) .byteLimit( 14 ), sample: mbSample, - useLimit: true, + hasLimit: true, limit: 14, - expected: 14 // (10 x 1-byte char) + (1 x 3-byte char) + (1 x 1-byte char) + expected: '1234567890' + U_20AC + '1' }); byteLimitTest({ description: 'Limit using a custom value (multibyte) overlapping a byte', $input: $( '<input>' ) - .attr( { - 'type': 'text' - }) + .attr( 'type', 'text' ) .byteLimit( 12 ), sample: mbSample, - useLimit: true, + hasLimit: true, limit: 12, - expected: 12 // 10 x 1-byte char. The next 3-byte char exceeds limit of 12, but 2 more 1-byte chars come in after. + expected: '1234567890' + '12' }); + +byteLimitTest({ + description: 'Pass the limit and a callback as input filter', + $input: $( '<input>' ) + .attr( 'type', 'text' ) + .byteLimit( 6, function( val ) { + // Invalid title + if ( val == '' ) { + return ''; + } + + // Return without namespace prefix + return new mw.Title( '' + val ).getMain(); + } ), + sample: 'User:Sample', + hasLimit: true, + limit: 6, // 'Sample' length + expected: 'User:Sample' +}); + +byteLimitTest({ + description: 'Limit using the maxlength attribute and pass a callback as input filter', + $input: $( '<input>' ) + .attr( 'type', 'text' ) + .prop( 'maxLength', '6' ) + .byteLimit( function( val ) { + // Invalid title + if ( val === '' ) { + return ''; + } + + // Return without namespace prefix + return new mw.Title( '' + val ).getMain(); + } ), + sample: 'User:Sample', + hasLimit: true, + limit: 6, // 'Sample' length + expected: 'User:Sample' +}); + +}() );
\ No newline at end of file diff --git a/tests/qunit/suites/resources/jquery/jquery.client.js b/tests/qunit/suites/resources/jquery/jquery.client.test.js index 50df2928..7be41971 100644 --- a/tests/qunit/suites/resources/jquery/jquery.client.js +++ b/tests/qunit/suites/resources/jquery/jquery.client.test.js @@ -1,12 +1,14 @@ -module( 'jquery.client.js' ); +module( 'jquery.client', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(1); ok( jQuery.client, 'jQuery.client defined' ); }); -test( 'profile userAgent support', function() { - expect(8); +/** Number of user-agent defined */ +var uacount = 0; + +var uas = (function() { // 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/ @@ -24,11 +26,32 @@ test( 'profile userAgent support', function() { "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": "unknown", // should be able to report 6? + "platform": "win", + "version": "10.0", + "versionBase": "10", + "versionNumber": 10 + }, + 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': { @@ -42,6 +65,10 @@ test( 'profile userAgent support', function() { "version": "3.5.19", "versionBase": "3", "versionNumber": 3.5 + }, + wikiEditor: { + ltr: true, + rtl: true } }, // Firefox 3.6 @@ -56,6 +83,10 @@ test( 'profile userAgent support', function() { "version": "3.6.17", "versionBase": "3", "versionNumber": 3.6 + }, + wikiEditor: { + ltr: true, + rtl: true } }, // Firefox 4 @@ -70,7 +101,29 @@ test( 'profile userAgent support', function() { "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 + } }, // Firefox 5 // Safari 3 @@ -86,7 +139,11 @@ test( 'profile userAgent support', function() { "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', @@ -99,6 +156,10 @@ test( 'profile userAgent support', function() { "version": "4.0.5", "versionBase": "4", "versionNumber": 4 + }, + wikiEditor: { + ltr: true, + rtl: true } }, // Safari 5 @@ -122,6 +183,10 @@ test( 'profile userAgent support', function() { "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': { @@ -135,9 +200,19 @@ test( 'profile userAgent support', function() { "version": "12.0.742.68", "versionBase": "12", "versionNumber": 12 + }, + wikiEditor: { + ltr: true, + rtl: true } } }; + $.each( uas, function() { uacount++ }); + return uas; +})(); + +test( 'profile userAgent support', function() { + expect(uacount); // Generate a client profile object and compare recursively var uaTest = function( rawUserAgent, data ) { @@ -168,34 +243,37 @@ test( 'profile return validation for current user agent', function() { equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' ); }); +// Example from WikiEditor +// Make sure to use raw numbers, a string like "7.0" would fail on a +// version 10 browser since in string comparaison "10" is before "7.0" :) +var testMap = { + 'ltr': { + 'msie': [['>=', 7.0]], + 'firefox': [['>=', 2]], + 'opera': [['>=', 9.6]], + 'safari': [['>=', 3]], + 'chrome': [['>=', 3]], + 'netscape': [['>=', 9]], + 'blackberry': false, + 'ipod': false, + 'iphone': false + }, + 'rtl': { + 'msie': [['>=', 8]], + 'firefox': [['>=', 2]], + 'opera': [['>=', 9.6]], + 'safari': [['>=', 3]], + 'chrome': [['>=', 3]], + 'netscape': [['>=', 9]], + 'blackberry': false, + 'ipod': false, + 'iphone': false + } +}; + test( 'test', function() { expect(1); - // Example from WikiEditor - var testMap = { - 'ltr': { - 'msie': [['>=', 7]], - '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 - } - }; // .test() uses eval, make sure no exceptions are thrown // then do a basic return value type check var testMatch = $.client.test( testMap ); @@ -203,3 +281,29 @@ test( 'test', function() { equal( typeof testMatch, 'boolean', 'test returns a boolean value' ); }); + +test( 'User-agent matches against WikiEditor\'s compatibility map', function() { + expect( uacount * 2 ); // double since we test both LTR and RTL + + var $body = $( 'body' ), + bodyClasses = $body.attr( 'class' ); + + // Loop through and run tests + $.each( uas, function ( agent, data ) { + $.each( ['ltr', 'rtl'], function ( i, dir ) { + $body.removeClass( 'ltr rtl' ).addClass( dir ); + var profile = $.client.profile( { + userAgent: agent, + platform: data.platform + } ); + var testMatch = $.client.test( testMap, profile ); + $body.removeClass( dir ); + + equal( testMatch, data.wikiEditor[dir], 'testing comparison based on ' + dir + ', ' + agent ); + }); + }); + + // Restore body classes + $body.attr( 'class', bodyClasses ); +}); + diff --git a/tests/qunit/suites/resources/jquery/jquery.colorUtil.js b/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js index 93f12b82..655ee564 100644 --- a/tests/qunit/suites/resources/jquery/jquery.colorUtil.js +++ b/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js @@ -1,4 +1,4 @@ -module( 'jquery.colorUtil.js' ); +module( 'jquery.colorUtil', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(1); diff --git a/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js b/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js index 8688f12e..6489a1f1 100644 --- a/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js @@ -1,5 +1,5 @@ test('jquery.delayedBind with data option', function() { - var $fixture = $('<div>').appendTo('body'), + var $fixture = $('<div>').appendTo('#qunit-fixture'), data = { magic: "beeswax" }, delay = 50; @@ -20,7 +20,7 @@ test('jquery.delayedBind with data option', function() { }); test('jquery.delayedBind without data option', function() { - var $fixture = $('<div>').appendTo('body'), + var $fixture = $('<div>').appendTo('#qunit-fixture'), data = { magic: "beeswax" }, delay = 50; diff --git a/tests/qunit/suites/resources/jquery/jquery.getAttrs.js b/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js index 3d3d01e1..9377a2f6 100644 --- a/tests/qunit/suites/resources/jquery/jquery.getAttrs.js +++ b/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js @@ -1,4 +1,4 @@ -module( 'jquery.getAttrs.js' ); +module( 'jquery.getAttrs', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(1); diff --git a/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js b/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js new file mode 100644 index 00000000..4750d2b8 --- /dev/null +++ b/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js @@ -0,0 +1,239 @@ +module( 'jquery.highlightText', QUnit.newMwEnvironment() ); + +test( '-- Initial check', function() { + expect(1); + ok( $.fn.highlightText, 'jQuery.fn.highlightText defined' ); +} ); + +test( 'Check', function() { + var 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>ل إيردوس' + } + ]; + expect(cases.length); + var $fixture; + + $.each(cases, function( i, item ) { + $fixture = $( '<p></p>' ).text( item.text ); + $fixture.highlightText( item.highlight ); + equals( + $fixture.html(), + $('<p>' + item.expected + '</p>').html(), // re-parse to normalize! + item.desc || undefined + ); + } ); +} ); diff --git a/tests/qunit/suites/resources/jquery/jquery.localize.js b/tests/qunit/suites/resources/jquery/jquery.localize.test.js index 40b58687..cd828634 100644 --- a/tests/qunit/suites/resources/jquery/jquery.localize.js +++ b/tests/qunit/suites/resources/jquery/jquery.localize.test.js @@ -1,4 +1,4 @@ -module( 'jquery.localize.js' ); +module( 'jquery.localize', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(1); diff --git a/tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js b/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js index bb6d2a1b..3a2d0d83 100644 --- a/tests/qunit/suites/resources/jquery/jquery.mwPrototypes.js +++ b/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js @@ -1,10 +1,10 @@ -module( 'jquery.mwPrototypes.js' ); +module( 'jquery.mwExtension', QUnit.newMwEnvironment() ); test( 'String functions', function() { equal( $.trimLeft( ' foo bar ' ), 'foo bar ', 'trimLeft' ); equal( $.trimRight( ' foo bar ' ), ' foo bar', 'trimRight' ); - equal( $.ucFirst( 'foo'), 'Foo', 'ucFirst' ); + equal( $.ucFirst( 'foo' ), 'Foo', 'ucFirst' ); equal( $.escapeRE( '<!-- ([{+mW+}]) $^|?>' ), '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' ); @@ -36,6 +36,8 @@ test( 'Is functions', function() { strictEqual( $.isEmpty( 'string' ), false, 'isEmptry: "string"' ); strictEqual( $.isEmpty( '0' ), true, 'isEmptry: "0"' ); + strictEqual( $.isEmpty( '' ), true, 'isEmptry: ""' ); + strictEqual( $.isEmpty( 1 ), false, 'isEmptry: 1' ); strictEqual( $.isEmpty( [] ), true, 'isEmptry: []' ); strictEqual( $.isEmpty( {} ), true, 'isEmptry: {}' ); diff --git a/tests/qunit/suites/resources/jquery/jquery.tabIndex.js b/tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js index 1ff81e58..98ff5508 100644 --- a/tests/qunit/suites/resources/jquery/jquery.tabIndex.js +++ b/tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js @@ -1,4 +1,4 @@ -module( 'jquery.tabIndex.js' ); +module( 'jquery.tabIndex', QUnit.newMwEnvironment() ); test( '-- Initial check', function() { expect(2); @@ -18,14 +18,11 @@ test( 'firstTabIndex', function() { '<textarea tabindex="5">Foobar</textarea>' + '</form>'; - var $testA = $( '<div>' ).html( testEnvironment ).appendTo( 'body' ); + var $testA = $( '<div>' ).html( testEnvironment ).appendTo( '#qunit-fixture' ); strictEqual( $testA.firstTabIndex(), 2, 'First tabindex should be 2 within this context.' ); var $testB = $( '<div>' ); strictEqual( $testB.firstTabIndex(), null, 'Return null if none available.' ); - - // Clean up - $testA.add( $testB ).remove(); }); test( 'lastTabIndex', function() { @@ -39,12 +36,9 @@ test( 'lastTabIndex', function() { '<textarea tabindex="5">Foobar</textarea>' + '</form>'; - var $testA = $( '<div>' ).html( testEnvironment ).appendTo( 'body' ); + var $testA = $( '<div>' ).html( testEnvironment ).appendTo( '#qunit-fixture' ); strictEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' ); var $testB = $( '<div>' ); strictEqual( $testB.lastTabIndex(), null, 'Return null if none available.' ); - - // Clean up - $testA.add( $testB ).remove(); }); diff --git a/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js b/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js index f47b7f40..7ecdc4b1 100644 --- a/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js @@ -1,11 +1,13 @@ -(function() { +( function () { -module( 'jquery.tablesorter.test.js' ); +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', + wgContentLanguage: 'en' +}; -// setup hack -mw.config.set('wgMonthNames', window.wgMonthNames = ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']); -mw.config.set('wgMonthNamesShort', window.wgMonthNamesShort = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']); -mw.config.set('wgDefaultDateFormat', window.wgDefaultDateFormat = 'dmy'); +module( 'jquery.tablesorter', QUnit.newMwEnvironment( config ) ); test( '-- Initial check', function() { expect(1); @@ -21,23 +23,24 @@ test( '-- Initial check', function() { * @return jQuery */ var tableCreate = function( header, data ) { - var $table = $('<table class="sortable"><thead></thead><tbody></tbody></table>'), - $thead = $table.find('thead'), - $tbody = $table.find('tbody'); - var $tr = $('<tr>'); - $.each(header, function(i, str) { - var $th = $('<th>'); - $th.text(str).appendTo($tr); + var $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); + $tr.appendTo( $thead ); for (var i = 0; i < data.length; i++) { - $tr = $('<tr>'); - $.each(data[i], function(j, str) { - var $td = $('<td>'); - $td.text(str).appendTo($tr); + $tr = $( '<tr>' ); + $.each( data[i], function( j, str ) { + var $td = $( '<td>' ); + $td.text( str ).appendTo( $tr ); }); - $tr.appendTo($tbody); + $tr.appendTo( $tbody ); } return $table; }; @@ -50,12 +53,13 @@ var tableCreate = function( header, data ) { */ var tableExtract = function( $table ) { var data = []; - $table.find('tbody').find('tr').each(function(i, tr) { + + $table.find( 'tbody' ).find( 'tr' ).each( function( i, tr ) { var row = []; - $(tr).find('td,th').each(function(i, td) { - row.push($(td).text()); + $( tr ).find( 'td,th' ).each( function( i, td ) { + row.push( $( td ).text() ); }); - data.push(row); + data.push( row ); }); return data; }; @@ -75,7 +79,6 @@ var tableTest = function( msg, header, data, expected, callback ) { expect(1); var $table = tableCreate( header, data ); - //$('body').append($table); // Give caller a chance to set up sorting and manipulate the table. callback( $table ); @@ -93,18 +96,18 @@ var reversed = function(arr) { return arr2; }; -// Sample data set: some planets! -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']; +// 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 planets = [mercury, venus, earth, mars, jupiter, saturn]; +var ascendingName = [earth, jupiter, mars, mercury, saturn, venus]; var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter]; tableTest( @@ -114,7 +117,7 @@ tableTest( ascendingName, function( $table ) { $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); tableTest( @@ -124,7 +127,7 @@ tableTest( ascendingName, function( $table ) { $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); tableTest( @@ -134,7 +137,7 @@ tableTest( reversed(ascendingName), function( $table ) { $table.tablesorter(); - $table.find('.headerSort:eq(0)').click().click(); + $table.find( '.headerSort:eq(0)' ).click().click(); } ); tableTest( @@ -144,7 +147,7 @@ tableTest( ascendingRadius, function( $table ) { $table.tablesorter(); - $table.find('.headerSort:eq(1)').click(); + $table.find( '.headerSort:eq(1)' ).click(); } ); tableTest( @@ -154,25 +157,23 @@ tableTest( reversed(ascendingRadius), function( $table ) { $table.tablesorter(); - $table.find('.headerSort:eq(1)').click().click(); + $table.find( '.headerSort:eq(1)' ).click().click(); } ); // Regression tests! tableTest( - 'Bug 28775: German-style short numeric dates', + 'Bug 28775: German-style (dmy) short numeric dates', ['Date'], - [ - // German-style dates are day-month-year + [ // 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 + [ // Sorted by ascending date ['03.08.2011'], ['02.10.2011'], ['01.11.2011'], @@ -180,25 +181,25 @@ tableTest( ['11.11.2011'] ], function( $table ) { - // @fixme reset it at end or change module to allow us to override it - mw.config.set('wgDefaultDateFormat', window.wgDefaultDateFormat = 'dmy'); + mw.config.set( 'wgDefaultDateFormat', 'dmy' ); + mw.config.set( 'wgContentLanguage', 'de' ); + $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); + tableTest( - 'Bug 28775: American-style short numeric dates', + 'Bug 28775: American-style (mdy) short numeric dates', ['Date'], - [ - // American-style dates are month-day-year + [ // 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 + [ // Sorted by ascending date ['01.11.2011'], ['02.10.2011'], ['03.08.2011'], @@ -206,10 +207,10 @@ tableTest( ['11.11.2011'] ], function( $table ) { - // @fixme reset it at end or change module to allow us to override it - mw.config.set('wgDefaultDateFormat', window.wgDefaultDateFormat = 'mdy'); + mw.config.set( 'wgDefaultDateFormat', 'mdy' ); + $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); @@ -235,6 +236,7 @@ var ipv4Sorted = [ ['204.204.132.158'], ['247.240.82.209'] ]; + tableTest( 'Bug 17141: IPv4 address sorting', ['IP'], @@ -242,7 +244,7 @@ tableTest( ipv4Sorted, function( $table ) { $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); tableTest( @@ -252,7 +254,7 @@ tableTest( reversed(ipv4Sorted), function( $table ) { $table.tablesorter(); - $table.find('.headerSort:eq(0)').click().click(); + $table.find( '.headerSort:eq(0)' ).click().click(); } ); @@ -286,27 +288,36 @@ tableTest( umlautWords, umlautWordsSorted, function( $table ) { - mw.config.set('tableSorterCollation', {'ä':'ae', 'ö' : 'oe', 'ß': 'ss', 'ü':'ue'}); + mw.config.set( 'tableSorterCollation', { + 'ä': 'ae', + 'ö': 'oe', + 'ß': 'ss', + 'ü':'ue' + } ); + $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); - mw.config.set('tableSorterCollation', {}); + $table.find( '.headerSort:eq(0)' ).click(); } ); -var planetsRowspan =[["Earth","6051.8"], jupiter, ["Mars","6051.8"], mercury, saturn, venus]; -var planetsRowspanII =[jupiter, mercury, saturn, ['Venus', '6371.0'], venus, ['Venus', '3390.0']]; +var planetsRowspan = [["Earth","6051.8"], jupiter, ["Mars","6051.8"], mercury, saturn, venus]; +var planetsRowspanII = [jupiter, mercury, saturn, ['Venus', '6371.0'], venus, ['Venus', '3390.0']]; tableTest( - 'Basic planet table: Same value for multiple rows via rowspan', + 'Basic planet table: same value for multiple rows via rowspan', header, planets, planetsRowspan, function( $table ) { - //Quick&Dirty mod - $table.find('tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)').remove(); - $table.find('tr:eq(2) td:eq(1)').attr('rowspan', '3'); + // Modify the table to have a multiuple-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)' ).prop( 'rowspan', '3' ); + $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); tableTest( @@ -315,11 +326,15 @@ tableTest( planets, planetsRowspanII, function( $table ) { - //Quick&Dirty mod - $table.find('tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)').remove(); - $table.find('tr:eq(2) td:eq(0)').attr('rowspan', '3'); + // Modify the table to have a multiuple-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)' ).prop( 'rowspan', '3' ); + $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); @@ -346,9 +361,10 @@ tableTest( complexMDYDates, complexMDYSorted, function( $table ) { - mw.config.set('wgDefaultDateFormat', window.wgDefaultDateFormat = 'mdy'); + mw.config.set( 'wgDefaultDateFormat', 'mdy' ); + $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); @@ -362,9 +378,9 @@ tableTest( planets, ascendingNameLegacy, function( $table ) { - $table.find('tr:last').addClass('sortbottom'); + $table.find( 'tr:last' ).addClass( 'sortbottom' ); $table.tablesorter(); - $table.find('.headerSort:eq(0)').click(); + $table.find( '.headerSort:eq(0)' ).click(); } ); @@ -472,4 +488,65 @@ test( 'data-sort-value attribute, when available, should override sorting positi }); +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 + +test( 'bug 32888 - Tables inside a tableheader cell', function() { + expect(2); + + var $table; + $table = $( + '<table class="sortable" id="32888">' + + '<tr><th>header<table id="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(); + + equals( + $table.find('> thead:eq(0) > tr > th.headerSort').length, + 1, + 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)' + ); + equals( + $('#32888-2').find('th.headerSort').length, + 0, + 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)' + ); +}); + })(); diff --git a/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js b/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js new file mode 100644 index 00000000..1b2f3024 --- /dev/null +++ b/tests/qunit/suites/resources/jquery/jquery.textSelection.test.js @@ -0,0 +1,279 @@ +module( 'jquery.textSelection', QUnit.newMwEnvironment() ); + +test( '-- Initial check', function() { + expect(1); + ok( $.fn.textSelection, 'jQuery.fn.textSelection defined' ); +} ); + +/** + * 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' ) + */ +var encapsulateTest = function( 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); + + test( opt.description, function() { + var tests = 1; + if ( opt.after.selected !== null ) { + tests++; + } + 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; + if ( window.opera ) { + // Compensate for Opera's craziness converting "\n" to "\r\n" and counting that as two chars + var newLinesBefore = opt.before.text.substring( 0, start ).split( "\n" ).length - 1, + newLinesInside = opt.before.text.substring( start, end ).split( "\n" ).length - 1; + start += newLinesBefore; + end += newLinesBefore + newLinesInside; + } + + 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" ); + + equal( text, opt.after.text, 'Checking full text after encapsulation' ); + + if (opt.after.selected !== null) { + var selected = $textarea.textSelection( 'getSelection' ); + equal( selected, opt.after.selected, 'Checking selected text after encapsulation.' ); + } + + } ); +}; + +var 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 +}); + + +var caretTest = function(options) { + test(options.description, function() { + expect(2); + + var $textarea = $( '<textarea>' ).text(options.text); + + $( '#qunit-fixture' ).append( $textarea ); + + if (options.mode == 'set') { + $textarea.textSelection('setSelection', { + start: options.start, + end: options.end + }); + } + + var among = function(actual, expected, message) { + if ($.isArray(expected)) { + ok($.inArray(actual, expected) !== -1 , message + ' (got ' + actual + '; expected one of ' + expected.join(', ') + ')'); + } else { + equal(actual, expected, message); + } + }; + + var 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.'); + }); +} + +var caretSample = "Some big text that we like to work with. Nothing fancy... you know what I mean?"; + +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' +}); + |