Pass phpcs-strict on some test files (9/11)
[mediawiki.git] / tests / qunit / suites / resources / mediawiki / mediawiki.Title.test.js
blobf5fd16dbe2c239b17fc7a258f12b1392bb31fdff
1 /*jshint -W024 */
2 ( function ( mw, $ ) {
3         // mw.Title relies on these three config vars
4         // Restore them after each test run
5         var config = {
6                 wgFormattedNamespaces: {
7                         '-2': 'Media',
8                         '-1': 'Special',
9                         0: '',
10                         1: 'Talk',
11                         2: 'User',
12                         3: 'User talk',
13                         4: 'Wikipedia',
14                         5: 'Wikipedia talk',
15                         6: 'File',
16                         7: 'File talk',
17                         8: 'MediaWiki',
18                         9: 'MediaWiki talk',
19                         10: 'Template',
20                         11: 'Template talk',
21                         12: 'Help',
22                         13: 'Help talk',
23                         14: 'Category',
24                         15: 'Category talk',
25                         // testing custom / localized namespace
26                         100: 'Penguins'
27                 },
28                 wgNamespaceIds: {
29                         'media': -2,
30                         'special': -1,
31                         '': 0,
32                         'talk': 1,
33                         'user': 2,
34                         'user_talk': 3,
35                         'wikipedia': 4,
36                         'wikipedia_talk': 5,
37                         'file': 6,
38                         'file_talk': 7,
39                         'mediawiki': 8,
40                         'mediawiki_talk': 9,
41                         'template': 10,
42                         'template_talk': 11,
43                         'help': 12,
44                         'help_talk': 13,
45                         'category': 14,
46                         'category_talk': 15,
47                         'image': 6,
48                         'image_talk': 7,
49                         'project': 4,
50                         'project_talk': 5,
51                         // Testing custom namespaces and aliases
52                         'penguins': 100,
53                         'antarctic_waterfowl': 100
54                 },
55                 wgCaseSensitiveNamespaces: []
56         },
57         repeat = function ( input, multiplier ) {
58                 return new Array( multiplier + 1 ).join( input );
59         },
60         cases = {
61                 // See also TitleTest.php#testSecureAndSplit
62                 valid: [
63                         'Sandbox',
64                         'A "B"',
65                         'A \'B\'',
66                         '.com',
67                         '~',
68                         '"',
69                         '\'',
70                         'Talk:Sandbox',
71                         'Talk:Foo:Sandbox',
72                         'File:Example.svg',
73                         'File_talk:Example.svg',
74                         'Foo/.../Sandbox',
75                         'Sandbox/...',
76                         'A~~',
77                         // Length is 256 total, but only title part matters
78                         'Category:' + repeat( 'x', 248 ),
79                         repeat( 'x', 252 )
80                 ],
81                 invalid: [
82                         '',
83                         ':',
84                         '__  __',
85                         '  __  ',
86                         // Bad characters forbidden regardless of wgLegalTitleChars
87                         'A [ B',
88                         'A ] B',
89                         'A { B',
90                         'A } B',
91                         'A < B',
92                         'A > B',
93                         'A | B',
94                         // URL encoding
95                         'A%20B',
96                         'A%23B',
97                         'A%2523B',
98                         // XML/HTML character entity references
99                         // Note: The ones with # are commented out as those are interpreted as fragment and
100                         // as such end up being valid.
101                         'A &eacute; B',
102                         //'A &#233; B',
103                         //'A &#x00E9; B',
104                         // Subject of NS_TALK does not roundtrip to NS_MAIN
105                         'Talk:File:Example.svg',
106                         // Directory navigation
107                         '.',
108                         '..',
109                         './Sandbox',
110                         '../Sandbox',
111                         'Foo/./Sandbox',
112                         'Foo/../Sandbox',
113                         'Sandbox/.',
114                         'Sandbox/..',
115                         // Tilde
116                         'A ~~~ Name',
117                         'A ~~~~ Signature',
118                         'A ~~~~~ Timestamp',
119                         repeat( 'x', 256 ),
120                         // Extension separation is a js invention, for length
121                         // purposes it is part of the title
122                         repeat( 'x', 252 ) + '.json',
123                         // Namespace prefix without actual title
124                         'Talk:',
125                         'Category: ',
126                         'Category: #bar'
127                 ]
128         };
130         QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment( { config: config } ) );
132         QUnit.test( 'constructor', cases.invalid.length, function ( assert ) {
133                 var i, title;
134                 for ( i = 0; i < cases.valid.length; i++ ) {
135                         title = new mw.Title( cases.valid[i] );
136                 }
137                 for ( i = 0; i < cases.invalid.length; i++ ) {
138                         /*jshint loopfunc:true */
139                         title = cases.invalid[i];
140                         assert.throws( function () {
141                                 return new mw.Title( title );
142                         }, cases.invalid[i] );
143                 }
144         } );
146         QUnit.test( 'newFromText', cases.valid.length + cases.invalid.length, function ( assert ) {
147                 var i;
148                 for ( i = 0; i < cases.valid.length; i++ ) {
149                         assert.equal(
150                                 $.type( mw.Title.newFromText( cases.valid[i] ) ),
151                                 'object',
152                                 cases.valid[i]
153                         );
154                 }
155                 for ( i = 0; i < cases.invalid.length; i++ ) {
156                         assert.equal(
157                                 $.type( mw.Title.newFromText( cases.invalid[i] ) ),
158                                 'null',
159                                 cases.invalid[i]
160                         );
161                 }
162         } );
164         QUnit.test( 'Basic parsing', 12, function ( assert ) {
165                 var title;
166                 title = new mw.Title( 'File:Foo_bar.JPG' );
168                 assert.equal( title.getNamespaceId(), 6 );
169                 assert.equal( title.getNamespacePrefix(), 'File:' );
170                 assert.equal( title.getName(), 'Foo_bar' );
171                 assert.equal( title.getNameText(), 'Foo bar' );
172                 assert.equal( title.getExtension(), 'JPG' );
173                 assert.equal( title.getDotExtension(), '.JPG' );
174                 assert.equal( title.getMain(), 'Foo_bar.JPG' );
175                 assert.equal( title.getMainText(), 'Foo bar.JPG' );
176                 assert.equal( title.getPrefixedDb(), 'File:Foo_bar.JPG' );
177                 assert.equal( title.getPrefixedText(), 'File:Foo bar.JPG' );
179                 title = new mw.Title( 'Foo#bar' );
180                 assert.equal( title.getPrefixedText(), 'Foo' );
181                 assert.equal( title.getFragment(), 'bar' );
182         } );
184         QUnit.test( 'Transformation', 11, function ( assert ) {
185                 var title;
187                 title = new mw.Title( 'File:quux pif.jpg' );
188                 assert.equal( title.getNameText(), 'Quux pif', 'First character of title' );
190                 title = new mw.Title( 'File:Glarg_foo_glang.jpg' );
191                 assert.equal( title.getNameText(), 'Glarg foo glang', 'Underscores' );
193                 title = new mw.Title( 'User:ABC.DEF' );
194                 assert.equal( title.toText(), 'User:ABC.DEF', 'Round trip text' );
195                 assert.equal( title.getNamespaceId(), 2, 'Parse canonical namespace prefix' );
197                 title = new mw.Title( 'Image:quux pix.jpg' );
198                 assert.equal( title.getNamespacePrefix(), 'File:', 'Transform alias to canonical namespace' );
200                 title = new mw.Title( 'uSEr:hAshAr' );
201                 assert.equal( title.toText(), 'User:HAshAr' );
202                 assert.equal( title.getNamespaceId(), 2, 'Case-insensitive namespace prefix' );
204                 // Don't ask why, it's the way the backend works. One space is kept of each set.
205                 title = new mw.Title( 'Foo  __  \t __ bar' );
206                 assert.equal( title.getMain(), 'Foo_bar', 'Merge multiple types of whitespace/underscores into a single underscore' );
208                 // Regression test: Previously it would only detect an extension if there is no space after it
209                 title = new mw.Title( 'Example.js  ' );
210                 assert.equal( title.getExtension(), 'js', 'Space after an extension is stripped' );
212                 title = new mw.Title( 'Example#foo' );
213                 assert.equal( title.getFragment(), 'foo', 'Fragment' );
215                 title = new mw.Title( 'Example#_foo_bar baz_' );
216                 assert.equal( title.getFragment(), ' foo bar baz', 'Fragment' );
217         } );
219         QUnit.test( 'Namespace detection and conversion', 10, function ( assert ) {
220                 var title;
222                 title = new mw.Title( 'File:User:Example' );
223                 assert.equal( title.getNamespaceId(), 6, 'Titles can contain namespace prefixes, which are otherwise ignored' );
225                 title = new mw.Title( 'Example', 6 );
226                 assert.equal( title.getNamespaceId(), 6, 'Default namespace passed is used' );
228                 title = new mw.Title( 'User:Example', 6 );
229                 assert.equal( title.getNamespaceId(), 2, 'Included namespace prefix overrides the given default' );
231                 title = new mw.Title( ':Example', 6 );
232                 assert.equal( title.getNamespaceId(), 0, 'Colon forces main namespace' );
234                 title = new mw.Title( 'something.PDF', 6 );
235                 assert.equal( title.toString(), 'File:Something.PDF' );
237                 title = new mw.Title( 'NeilK', 3 );
238                 assert.equal( title.toString(), 'User_talk:NeilK' );
239                 assert.equal( title.toText(), 'User talk:NeilK' );
241                 title = new mw.Title( 'Frobisher', 100 );
242                 assert.equal( title.toString(), 'Penguins:Frobisher' );
244                 title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' );
245                 assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
247                 title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' );
248                 assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
249         } );
251         QUnit.test( 'Throw error on invalid title', 1, function ( assert ) {
252                 assert.throws( function () {
253                         return new mw.Title( '' );
254                 }, 'Throw error on empty string' );
255         } );
257         QUnit.test( 'Case-sensivity', 3, function ( assert ) {
258                 var title;
260                 // Default config
261                 mw.config.set( 'wgCaseSensitiveNamespaces', [] );
263                 title = new mw.Title( 'article' );
264                 assert.equal( title.toString(), 'Article', 'Default config: No sensitive namespaces by default. First-letter becomes uppercase' );
266                 // $wgCapitalLinks = false;
267                 mw.config.set( 'wgCaseSensitiveNamespaces', [0, -2, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15] );
269                 title = new mw.Title( 'article' );
270                 assert.equal( title.toString(), 'article', '$wgCapitalLinks=false: Article namespace is sensitive, first-letter case stays lowercase' );
272                 title = new mw.Title( 'john', 2 );
273                 assert.equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' );
274         } );
276         QUnit.test( 'toString / toText', 2, function ( assert ) {
277                 var title = new mw.Title( 'Some random page' );
279                 assert.equal( title.toString(), title.getPrefixedDb() );
280                 assert.equal( title.toText(), title.getPrefixedText() );
281         } );
283         QUnit.test( 'getExtension', 7, function ( assert ) {
284                 function extTest( pagename, ext, description ) {
285                         var title = new mw.Title( pagename );
286                         assert.equal( title.getExtension(), ext, description || pagename );
287                 }
289                 extTest( 'MediaWiki:Vector.js', 'js' );
290                 extTest( 'User:Example/common.css', 'css' );
291                 extTest( 'File:Example.longextension', 'longextension', 'Extension parsing not limited (bug 36151)' );
292                 extTest( 'Example/information.json', 'json', 'Extension parsing not restricted from any namespace' );
293                 extTest( 'Foo.', null, 'Trailing dot is not an extension' );
294                 extTest( 'Foo..', null, 'Trailing dots are not an extension' );
295                 extTest( 'Foo.a.', null, 'Page name with dots and ending in a dot does not have an extension' );
297                 // @broken: Throws an exception
298                 // extTest( '.NET', null, 'Leading dot is (or is not?) an extension' );
299         } );
301         QUnit.test( 'exists', 3, function ( assert ) {
302                 var title;
304                 // Empty registry, checks default to null
306                 title = new mw.Title( 'Some random page', 4 );
307                 assert.strictEqual( title.exists(), null, 'Return null with empty existance registry' );
309                 // Basic registry, checks default to boolean
310                 mw.Title.exist.set( ['Does_exist', 'User_talk:NeilK', 'Wikipedia:Sandbox_rules'], true );
311                 mw.Title.exist.set( ['Does_not_exist', 'User:John', 'Foobar'], false );
313                 title = new mw.Title( 'Project:Sandbox rules' );
314                 assert.assertTrue( title.exists(), 'Return true for page titles marked as existing' );
315                 title = new mw.Title( 'Foobar' );
316                 assert.assertFalse( title.exists(), 'Return false for page titles marked as nonexistent' );
318         } );
320         QUnit.test( 'getUrl', 3, function ( assert ) {
321                 var title;
323                 // Config
324                 mw.config.set( 'wgArticlePath', '/wiki/$1' );
326                 title = new mw.Title( 'Foobar' );
327                 assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionality, getUrl uses mw.util.getUrl' );
328                 assert.equal( title.getUrl({ action: 'edit' }), '/wiki/Foobar?action=edit', 'Basic functionality, \'params\' parameter' );
330                 title = new mw.Title( 'John Doe', 3 );
331                 assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
332         } );
334         QUnit.test( 'newFromImg', 40, function ( assert ) {
335                 var title, i, thisCase, prefix,
336                         cases = [
337                                 {
338                                         url: '//upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Princess_Alexandra_of_Denmark_%28later_Queen_Alexandra%2C_wife_of_Edward_VII%29_with_her_two_eldest_sons%2C_Prince_Albert_Victor_%28Eddy%29_and_George_Frederick_Ernest_Albert_%28later_George_V%29.jpg/939px-thumbnail.jpg',
339                                         typeOfUrl: 'Hashed thumb with shortened path',
340                                         nameText: 'Princess Alexandra of Denmark (later Queen Alexandra, wife of Edward VII) with her two eldest sons, Prince Albert Victor (Eddy) and George Frederick Ernest Albert (later George V)',
341                                         prefixedText: 'File:Princess Alexandra of Denmark (later Queen Alexandra, wife of Edward VII) with her two eldest sons, Prince Albert Victor (Eddy) and George Frederick Ernest Albert (later George V).jpg'
342                                 },
343                                 {
344                                         url: '/wiki/images/thumb/9/91/Anticlockwise_heliotrope%27s.jpg/99px-Anticlockwise_heliotrope%27s.jpg',
345                                         typeOfUrl: 'Normal hashed directory thumbnail',
346                                         nameText: 'Anticlockwise heliotrope\'s',
347                                         prefixedText: 'File:Anticlockwise heliotrope\'s.jpg'
348                                 },
350                                 {
351                                         url: '/wiki/images/thumb/8/80/Wikipedia-logo-v2.svg/langde-150px-Wikipedia-logo-v2.svg.png',
352                                         typeOfUrl: 'Normal hashed directory thumbnail with complex thumbnail parameters',
353                                         nameText: 'Wikipedia-logo-v2',
354                                         prefixedText: 'File:Wikipedia-logo-v2.svg'
355                                 },
357                                 {
358                                         url: '//upload.wikimedia.org/wikipedia/commons/thumb/8/80/Wikipedia-logo-v2.svg/150px-Wikipedia-logo-v2.svg.png',
359                                         typeOfUrl: 'Commons thumbnail',
360                                         nameText: 'Wikipedia-logo-v2',
361                                         prefixedText: 'File:Wikipedia-logo-v2.svg'
362                                 },
364                                 {
365                                         url: '/wiki/images/9/91/Anticlockwise_heliotrope%27s.jpg',
366                                         typeOfUrl: 'Full image',
367                                         nameText: 'Anticlockwise heliotrope\'s',
368                                         prefixedText: 'File:Anticlockwise heliotrope\'s.jpg'
369                                 },
371                                 {
372                                         url: 'http://localhost/thumb.php?f=Stuffless_Figaro%27s.jpg&width=180',
373                                         typeOfUrl: 'thumb.php-based thumbnail',
374                                         nameText: 'Stuffless Figaro\'s',
375                                         prefixedText: 'File:Stuffless Figaro\'s.jpg'
376                                 },
378                                 {
379                                         url: '/wikipedia/commons/thumb/Wikipedia-logo-v2.svg/150px-Wikipedia-logo-v2.svg.png',
380                                         typeOfUrl: 'Commons unhashed thumbnail',
381                                         nameText: 'Wikipedia-logo-v2',
382                                         prefixedText: 'File:Wikipedia-logo-v2.svg'
383                                 },
385                                 {
386                                         url: '/wikipedia/commons/thumb/Wikipedia-logo-v2.svg/langde-150px-Wikipedia-logo-v2.svg.png',
387                                         typeOfUrl: 'Commons unhashed thumbnail with complex thumbnail parameters',
388                                         nameText: 'Wikipedia-logo-v2',
389                                         prefixedText: 'File:Wikipedia-logo-v2.svg'
390                                 },
392                                 {
393                                         url: '/wiki/images/Anticlockwise_heliotrope%27s.jpg',
394                                         typeOfUrl: 'Unhashed local file',
395                                         nameText: 'Anticlockwise heliotrope\'s',
396                                         prefixedText: 'File:Anticlockwise heliotrope\'s.jpg'
397                                 },
399                                 {
400                                         url: '',
401                                         typeOfUrl: 'Empty string'
402                                 },
404                                 {
405                                         url: 'foo',
406                                         typeOfUrl: 'String with only alphabet characters'
407                                 },
409                                 {
410                                         url: 'foobar.foobar',
411                                         typeOfUrl: 'Not a file path'
412                                 },
414                                 {
415                                         url: '/a/a0/blah blah blah',
416                                         typeOfUrl: 'Space characters'
417                                 }
418                         ];
420                 for ( i = 0; i < cases.length; i++ ) {
421                         thisCase = cases[i];
422                         title = mw.Title.newFromImg( { src: thisCase.url } );
424                         if ( thisCase.nameText !== undefined ) {
425                                 prefix = '[' + thisCase.typeOfUrl + ' URL' + '] ';
427                                 assert.notStrictEqual( title, null, prefix + 'Parses successfully' );
428                                 assert.equal( title.getNameText(), thisCase.nameText, prefix + 'Filename matches original' );
429                                 assert.equal( title.getPrefixedText(), thisCase.prefixedText, prefix + 'File page title matches original' );
430                                 assert.equal( title.getNamespaceId(), 6, prefix + 'Namespace ID matches File namespace' );
431                         } else {
432                                 assert.strictEqual( title, null, thisCase.typeOfUrl + ', should not produce an mw.Title object' );
433                         }
434                 }
435         } );
437 }( mediaWiki, jQuery ) );