3 // Based on IPTest.php > testisIPv4
5 [ false, false, 'Boolean false is not an IP' ],
6 [ false, true, 'Boolean true is not an IP' ],
7 [ false, '', 'Empty string is not an IP' ],
8 [ false, 'abc', '"abc" is not an IP' ],
9 [ false, ':', 'Colon is not an IP' ],
10 [ false, '124.24.52', 'IPv4 not enough quads' ],
11 [ false, '24.324.52.13', 'IPv4 out of range' ],
12 [ false, '.24.52.13', 'IPv4 starts with period' ],
14 [ true, '124.24.52.13', '124.24.52.134 is a valid IP' ],
15 [ true, '1.24.52.13', '1.24.52.13 is a valid IP' ],
16 [ false, '74.24.52.13/20', 'IPv4 ranges are not recognized as valid IPs' ]
19 // Based on IPTest.php > testisIPv6
21 [ false, ':fc:100::', 'IPv6 starting with lone ":"' ],
22 [ false, 'fc:100:::', 'IPv6 ending with a ":::"' ],
23 [ false, 'fc:300', 'IPv6 with only 2 words' ],
24 [ false, 'fc:100:300', 'IPv6 with only 3 words' ],
26 [ false, 'fc:100:a:d:1:e:ac:0::', 'IPv6 with 8 words ending with "::"' ],
27 [ false, 'fc:100:a:d:1:e:ac:0:1::', 'IPv6 with 9 words ending with "::"' ],
30 [ false, '::0:', 'IPv6 ending in a lone ":"' ],
32 [ true, '::', 'IPv6 zero address' ],
34 [ false, '::fc:100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' ],
35 [ false, '::fc:100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' ],
37 [ false, ':fc::100', 'IPv6 starting with lone ":"' ],
38 [ false, 'fc::100:', 'IPv6 ending with lone ":"' ],
39 [ false, 'fc:::100', 'IPv6 with ":::" in the middle' ],
41 [ true, 'fc::100', 'IPv6 with "::" and 2 words' ],
42 [ true, 'fc::100:a', 'IPv6 with "::" and 3 words' ],
43 [ true, 'fc::100:a:d', 'IPv6 with "::" and 4 words' ],
44 [ true, 'fc::100:a:d:1', 'IPv6 with "::" and 5 words' ],
45 [ true, 'fc::100:a:d:1:e', 'IPv6 with "::" and 6 words' ],
46 [ true, 'fc::100:a:d:1:e:ac', 'IPv6 with "::" and 7 words' ],
47 [ true, '2001::df', 'IPv6 with "::" and 2 words' ],
48 [ true, '2001:5c0:1400:a::df', 'IPv6 with "::" and 5 words' ],
49 [ true, '2001:5c0:1400:a::df:2', 'IPv6 with "::" and 6 words' ],
51 [ false, 'fc::100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' ],
52 [ false, 'fc::100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' ]
55 Array
.prototype.push
.apply( IPV6_CASES
,
62 'fc:100:a:d:1:e:ac::',
70 '::fc:100:a:d:1:e:ac',
73 return [ [ true, el
, el
+ ' is a valid IP' ] ];
77 QUnit
.module( 'mediawiki.util', QUnit
.newMwEnvironment( {
79 $.fn
.updateTooltipAccessKeys
.setTestMode( true );
81 teardown: function () {
82 $.fn
.updateTooltipAccessKeys
.setTestMode( false );
85 // Used by accessKeyLabel in test for addPortletLink
91 QUnit
.test( 'rawurlencode', 1, function ( assert
) {
92 assert
.equal( mw
.util
.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
95 QUnit
.test( 'wikiUrlencode', 10, function ( assert
) {
96 assert
.equal( mw
.util
.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
97 // See also wfUrlencodeTest.php#provideURLS
103 ';@$-_.!*\'': ';@$-_.!*\'',
108 }, function ( input
, output
) {
109 assert
.equal( mw
.util
.wikiUrlencode( input
), output
);
113 QUnit
.test( 'getUrl', 5, function ( assert
) {
114 // Not part of startUp module
115 mw
.config
.set( 'wgArticlePath', '/wiki/$1' );
116 mw
.config
.set( 'wgPageName', 'Foobar' );
118 var href
= mw
.util
.getUrl( 'Sandbox' );
119 assert
.equal( href
, '/wiki/Sandbox', 'simple title' );
121 href
= mw
.util
.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
122 assert
.equal( href
, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'advanced title' );
124 href
= mw
.util
.getUrl();
125 assert
.equal( href
, '/wiki/Foobar', 'default title' );
127 href
= mw
.util
.getUrl( null, { action
: 'edit' } );
128 assert
.equal( href
, '/wiki/Foobar?action=edit', 'default title with query string' );
130 href
= mw
.util
.getUrl( 'Sandbox', { action
: 'edit' } );
131 assert
.equal( href
, '/wiki/Sandbox?action=edit', 'simple title with query string' );
134 QUnit
.test( 'wikiScript', 4, function ( assert
) {
136 wgScript
: '/w/i.php', // customized wgScript for bug 39103
137 wgLoadScript
: '/w/l.php', // customized wgLoadScript for bug 39103
139 wgScriptExtension
: '.php'
142 assert
.equal( mw
.util
.wikiScript(), mw
.config
.get( 'wgScript' ),
143 'wikiScript() returns wgScript'
145 assert
.equal( mw
.util
.wikiScript( 'index' ), mw
.config
.get( 'wgScript' ),
146 'wikiScript( index ) returns wgScript'
148 assert
.equal( mw
.util
.wikiScript( 'load' ), mw
.config
.get( 'wgLoadScript' ),
149 'wikiScript( load ) returns wgLoadScript'
151 assert
.equal( mw
.util
.wikiScript( 'api' ), '/w/api.php', 'API path' );
154 QUnit
.test( 'addCSS', 3, function ( assert
) {
156 $el
= $( '<div>' ).attr( 'id', 'mw-addcsstest' ).appendTo( '#qunit-fixture' );
158 style
= mw
.util
.addCSS( '#mw-addcsstest { visibility: hidden; }' );
159 assert
.equal( typeof style
, 'object', 'addCSS returned an object' );
160 assert
.strictEqual( style
.disabled
, false, 'property "disabled" is available and set to false' );
162 assert
.equal( $el
.css( 'visibility' ), 'hidden', 'Added style properties are in effect' );
165 $( style
.ownerNode
).remove();
168 QUnit
.test( 'getParamValue', 5, function ( assert
) {
171 url
= 'http://example.org/?foo=wrong&foo=right#&foo=bad';
172 assert
.equal( mw
.util
.getParamValue( 'foo', url
), 'right', 'Use latest one, ignore hash' );
173 assert
.strictEqual( mw
.util
.getParamValue( 'bar', url
), null, 'Return null when not found' );
175 url
= 'http://example.org/#&foo=bad';
176 assert
.strictEqual( mw
.util
.getParamValue( 'foo', url
), null, 'Ignore hash if param is not in querystring but in hash (bug 27427)' );
178 url
= 'example.org?' + $.param( { TEST
: 'a b+c' } );
179 assert
.strictEqual( mw
.util
.getParamValue( 'TEST', url
), 'a b+c', 'Bug 30441: getParamValue must understand "+" encoding of space' );
181 url
= 'example.org?' + $.param( { TEST
: 'a b+c d' } ); // check for sloppy code from r95332 :)
182 assert
.strictEqual( mw
.util
.getParamValue( 'TEST', url
), 'a b+c d', 'Bug 30441: getParamValue must understand "+" encoding of space (multiple spaces)' );
185 QUnit
.test( 'tooltipAccessKey', 4, function ( assert
) {
186 this.suppressWarnings();
188 assert
.equal( typeof mw
.util
.tooltipAccessKeyPrefix
, 'string', 'tooltipAccessKeyPrefix must be a string' );
189 assert
.equal( $.type( mw
.util
.tooltipAccessKeyRegexp
), 'regexp', 'tooltipAccessKeyRegexp is a regexp' );
190 assert
.ok( mw
.util
.updateTooltipAccessKeys
, 'updateTooltipAccessKeys is non-empty' );
192 'Example [a]'.replace( mw
.util
.tooltipAccessKeyRegexp
, function ( sub
, m1
, m2
, m3
, m4
, m5
, m6
) {
193 assert
.equal( m6
, 'a', 'tooltipAccessKeyRegexp finds the accesskey hint' );
196 this.restoreWarnings();
199 QUnit
.test( '$content', 2, function ( assert
) {
200 assert
.ok( mw
.util
.$content
instanceof jQuery
, 'mw.util.$content instance of jQuery' );
201 assert
.strictEqual( mw
.util
.$content
.length
, 1, 'mw.util.$content must have length of 1' );
205 * Portlet names are prefixed with 'p-test' to avoid conflict with core
206 * when running the test suite under a wiki page.
207 * Previously, test elements where invisible to the selector since only
208 * one element can have a given id.
210 QUnit
.test( 'addPortletLink', 13, function ( assert
) {
211 var pTestTb
, pCustom
, vectorTabs
, tbRL
, cuQuux
, $cuQuux
, tbMW
, $tbMW
, tbRLDM
, caFoo
,
212 addedAfter
, tbRLDMnonexistentid
, tbRLDMemptyjquery
;
215 <div class="portlet" id="p-test-tb">\
217 <ul class="body"></ul>\
220 <div class="portlet" id="p-test-custom">\
223 <li id="c-foo"><a href="#">Foo</a></li>\
226 <li id="c-bar-baz"><a href="#">Baz</a></a>\
232 <div id="p-test-views" class="vectorTabs">\
237 $( '#qunit-fixture' ).append( pTestTb
, pCustom
, vectorTabs
);
239 tbRL
= mw
.util
.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader',
240 'ResourceLoader', 't-rl', 'More info about ResourceLoader on MediaWiki.org ', 'l'
243 assert
.ok( tbRL
&& tbRL
.nodeType
, 'addPortletLink returns a DOM Node' );
245 tbMW
= mw
.util
.addPortletLink( 'p-test-tb', '//mediawiki.org/',
246 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org', 'm', tbRL
);
254 'Validate attributes of created element'
258 $tbMW
.find( 'a' ).getAttrs(),
260 href
: '//mediawiki.org/',
261 title
: 'Go to MediaWiki.org [test-m]',
264 'Validate attributes of anchor tag in created element'
267 assert
.equal( $tbMW
.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' );
268 assert
.strictEqual( $tbMW
.next()[ 0 ], tbRL
, 'Link is in the correct position (nextnode as Node object)' );
270 cuQuux
= mw
.util
.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' );
271 $cuQuux
= $( cuQuux
);
273 assert
.equal( $cuQuux
.find( 'a' ).attr( 'title' ), 'Example [test-q]', 'Existing accesskey is stripped and updated' );
276 $( '#p-test-custom #c-barmenu ul li' ).length
,
278 'addPortletLink did not add the item to all <ul> elements in the portlet (bug 35082)'
281 tbRLDM
= mw
.util
.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
282 'Default modules', 't-rldm', 'List of all default modules ', 'd', '#t-rl' );
284 assert
.strictEqual( $( tbRLDM
).next()[ 0 ], tbRL
, 'Link is in the correct position (CSS selector as nextnode)' );
286 caFoo
= mw
.util
.addPortletLink( 'p-test-views', '#', 'Foo' );
288 assert
.strictEqual( $tbMW
.find( 'span' ).length
, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
289 assert
.strictEqual( $( caFoo
).find( 'span' ).length
, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
291 addedAfter
= mw
.util
.addPortletLink( 'p-test-tb', '#', 'After foo', 'post-foo', 'After foo', null, $( tbRL
) );
292 assert
.strictEqual( $( addedAfter
).next()[ 0 ], tbRL
, 'Link is in the correct position (jQuery object as nextnode)' );
294 // test case - nonexistent id as next node
295 tbRLDMnonexistentid
= mw
.util
.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
296 'Default modules', 't-rldm-nonexistent', 'List of all default modules ', 'd', '#t-rl-nonexistent' );
298 assert
.equal( tbRLDMnonexistentid
, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode non-matching CSS selector)' );
300 // test case - empty jquery object as next node
301 tbRLDMemptyjquery
= mw
.util
.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
302 'Default modules', 't-rldm-empty-jquery', 'List of all default modules ', 'd', $( '#t-rl-nonexistent' ) );
304 assert
.equal( tbRLDMemptyjquery
, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode as empty jQuery object)' );
307 QUnit
.test( 'validateEmail', 6, function ( assert
) {
308 assert
.strictEqual( mw
.util
.validateEmail( '' ), null, 'Should return null for empty string ' );
309 assert
.strictEqual( mw
.util
.validateEmail( 'user@localhost' ), true, 'Return true for a valid e-mail address' );
311 // testEmailWithCommasAreInvalids
312 assert
.strictEqual( mw
.util
.validateEmail( 'user,foo@example.org' ), false, 'Emails with commas are invalid' );
313 assert
.strictEqual( mw
.util
.validateEmail( 'userfoo@ex,ample.org' ), false, 'Emails with commas are invalid' );
315 // testEmailWithHyphens
316 assert
.strictEqual( mw
.util
.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
317 assert
.strictEqual( mw
.util
.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
320 QUnit
.test( 'isIPv6Address', 40, function ( assert
) {
321 $.each( IPV6_CASES
, function ( i
, ipCase
) {
322 assert
.strictEqual( mw
.util
.isIPv6Address( ipCase
[ 1 ] ), ipCase
[ 0 ], ipCase
[ 2 ] );
326 QUnit
.test( 'isIPv4Address', 11, function ( assert
) {
327 $.each( IPV4_CASES
, function ( i
, ipCase
) {
328 assert
.strictEqual( mw
.util
.isIPv4Address( ipCase
[ 1 ] ), ipCase
[ 0 ], ipCase
[ 2 ] );
332 QUnit
.test( 'isIPAddress', 51, function ( assert
) {
333 $.each( IPV4_CASES
, function ( i
, ipCase
) {
334 assert
.strictEqual( mw
.util
.isIPv4Address( ipCase
[ 1 ] ), ipCase
[ 0 ], ipCase
[ 2 ] );
337 $.each( IPV6_CASES
, function ( i
, ipCase
) {
338 assert
.strictEqual( mw
.util
.isIPv6Address( ipCase
[ 1 ] ), ipCase
[ 0 ], ipCase
[ 2 ] );
341 }( mediaWiki
, jQuery
) );