Fix failing qunit test for mediawiki.jqueryMsg
[lhc/web/wiklou.git] / tests / qunit / suites / resources / mediawiki / mediawiki.jqueryMsg.test.js
1 ( function ( mw, $ ) {
2
3 var mwLanguageCache = {}, oldGetOuterHtml;
4
5 QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
6 setup: function () {
7 this.orgMwLangauge = mw.language;
8 mw.language = $.extend( true, {}, this.orgMwLangauge );
9 oldGetOuterHtml = $.fn.getOuterHtml;
10 $.fn.getOuterHtml = function () {
11 var $div = $( '<div>' ), html;
12 $div.append( $( this ).eq( 0 ).clone() );
13 html = $div.html();
14 $div.empty();
15 $div = undefined;
16 return html;
17 };
18 },
19 teardown: function () {
20 mw.language = this.orgMwLangauge;
21 $.fn.getOuterHtml = oldGetOuterHtml;
22 }
23 }) );
24
25 function getMwLanguage( langCode, cb ) {
26 if ( mwLanguageCache[langCode] !== undefined ) {
27 mwLanguageCache[langCode].add( cb );
28 return;
29 }
30 mwLanguageCache[langCode] = $.Callbacks( 'once memory' );
31 mwLanguageCache[langCode].add( cb );
32 $.ajax({
33 url: mw.util.wikiScript( 'load' ),
34 data: {
35 skin: mw.config.get( 'skin' ),
36 lang: langCode,
37 debug: mw.config.get( 'debug' ),
38 modules: [
39 'mediawiki.language.data',
40 'mediawiki.language'
41 ].join( '|' ),
42 only: 'scripts'
43 },
44 dataType: 'script'
45 }).done( function () {
46 mwLanguageCache[langCode].fire( mw.language );
47 }).fail( function () {
48 mwLanguageCache[langCode].fire( false );
49 });
50 }
51
52 QUnit.test( 'Plural', 3, function ( assert ) {
53 var parser = mw.jqueryMsg.getMessageFunction();
54
55 mw.messages.set( 'plural-msg', 'Found $1 {{PLURAL:$1|item|items}}' );
56 assert.equal( parser( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' );
57 assert.equal( parser( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' );
58 assert.equal( parser( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
59 } );
60
61
62 QUnit.test( 'Gender', 11, function ( assert ) {
63 // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg
64 // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian
65 var user = mw.user,
66 parser = mw.jqueryMsg.getMessageFunction();
67
68 // The values here are not significant,
69 // what matters is which of the values is choosen by the parser
70 mw.messages.set( 'gender-msg', '$1: {{GENDER:$2|blue|pink|green}}' );
71
72 user.options.set( 'gender', 'male' );
73 assert.equal(
74 parser( 'gender-msg', 'Bob', 'male' ),
75 'Bob: blue',
76 'Masculine from string "male"'
77 );
78 assert.equal(
79 parser( 'gender-msg', 'Bob', user ),
80 'Bob: blue',
81 'Masculine from mw.user object'
82 );
83
84 user.options.set( 'gender', 'unknown' );
85 assert.equal(
86 parser( 'gender-msg', 'Foo', user ),
87 'Foo: green',
88 'Neutral from mw.user object' );
89 assert.equal(
90 parser( 'gender-msg', 'Alice', 'female' ),
91 'Alice: pink',
92 'Feminine from string "female"' );
93 assert.equal(
94 parser( 'gender-msg', 'User' ),
95 'User: green',
96 'Neutral when no parameter given' );
97 assert.equal(
98 parser( 'gender-msg', 'User', 'unknown' ),
99 'User: green',
100 'Neutral from string "unknown"'
101 );
102
103 mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
104
105 assert.equal(
106 parser( 'gender-msg-one-form', 'male', 10 ),
107 'User: 10 edits',
108 'Gender neutral and plural form'
109 );
110 assert.equal(
111 parser( 'gender-msg-one-form', 'female', 1 ),
112 'User: 1 edit',
113 'Gender neutral and singular form'
114 );
115
116 mw.messages.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' );
117 assert.equal(
118 parser( 'gender-msg-lowercase', 'male' ),
119 'he is awesome',
120 'Gender masculine'
121 );
122 assert.equal(
123 parser( 'gender-msg-lowercase', 'female' ),
124 'she is awesome',
125 'Gender feminine'
126 );
127
128 mw.messages.set( 'gender-msg-wrong', '{{gender}} test' );
129 assert.equal(
130 parser( 'gender-msg-wrong', 'female' ),
131 ' test',
132 'Invalid syntax should result in {{gender}} simply being stripped away'
133 );
134 } );
135
136 QUnit.test( 'Grammar', 2, function ( assert ) {
137 var parser = mw.jqueryMsg.getMessageFunction();
138
139 // Assume the grammar form grammar_case_foo is not valid in any language
140 mw.messages.set( 'grammar-msg', 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}' );
141 assert.equal( parser( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar Test with sitename' );
142
143 mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' );
144 assert.equal( parser( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ' , 'Grammar Test with wrong grammar template syntax' );
145 } );
146
147 QUnit.test( 'Output matches PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
148 mw.messages.set( mw.libs.phpParserData.messages );
149 $.each( mw.libs.phpParserData.tests, function ( i, test ) {
150 QUnit.stop();
151 getMwLanguage( test.lang, function ( langClass ) {
152 QUnit.start();
153 if ( !langClass ) {
154 assert.ok( false, 'Language "' + test.lang + '" failed to load' );
155 return;
156 }
157 mw.config.set( 'wgUserLanguage', test.lang ) ;
158 var parser = new mw.jqueryMsg.parser( { language: langClass } );
159 assert.equal(
160 parser.parse( test.key, test.args ).html(),
161 test.result,
162 test.name
163 );
164 } );
165 } );
166 });
167
168 QUnit.test( 'Links', 6, function ( assert ) {
169 var parser = mw.jqueryMsg.getMessageFunction(),
170 expectedListUsers,
171 expectedDisambiguationsText,
172 expectedMultipleBars,
173 expectedSpecialCharacters,
174 specialCharactersPageName;
175
176 /*
177 The below three are all identical to or based on real messages. For disambiguations-text,
178 the bold was removed because it is not yet implemented.
179 */
180
181 mw.messages.set( 'statistics-users', '注册[[Special:ListUsers|用户]]' );
182
183 expectedListUsers = '注册' + $( '<a>' ).attr( {
184 title: 'Special:ListUsers',
185 href: mw.util.wikiGetlink( 'Special:ListUsers' )
186 } ).text( '用户' ).getOuterHtml();
187
188 assert.equal(
189 parser( 'statistics-users' ),
190 expectedListUsers,
191 'Piped wikilink'
192 );
193
194 expectedDisambiguationsText = 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.<br>\nA page is treated as a disambiguation page if it uses a template that is linked from ' +
195 $( '<a>' ).attr( {
196 title: 'MediaWiki:Disambiguationspage',
197 href: mw.util.wikiGetlink( 'MediaWiki:Disambiguationspage' )
198 } ).text( 'MediaWiki:Disambiguationspage' ).getOuterHtml() + '.';
199 mw.messages.set( 'disambiguations-text', 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.<br />\nA page is treated as a disambiguation page if it uses a template that is linked from [[MediaWiki:Disambiguationspage]].' );
200 assert.equal(
201 parser( 'disambiguations-text' ),
202 expectedDisambiguationsText,
203 'Wikilink without pipe'
204 );
205
206 mw.messages.set( 'version-entrypoints-index-php', '[https://www.mediawiki.org/wiki/Manual:index.php index.php]' );
207 assert.equal(
208 parser( 'version-entrypoints-index-php' ),
209 '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>',
210 'External link'
211 );
212
213 // Pipe trick is not supported currently, but should not parse as text either.
214 mw.messages.set( 'pipe-trick', '[[Tampa, Florida|]]' );
215 assert.equal(
216 parser( 'pipe-trick' ),
217 'pipe-trick: Parse error at position 0 in input: [[Tampa, Florida|]]',
218 'Pipe trick should return error string.'
219 );
220
221 expectedMultipleBars = $( '<a>' ).attr( {
222 title: 'Main Page',
223 href: mw.util.wikiGetlink( 'Main Page' )
224 } ).text( 'Main|Page' ).getOuterHtml();
225 mw.messages.set( 'multiple-bars', '[[Main Page|Main|Page]]' );
226 assert.equal(
227 parser( 'multiple-bars' ),
228 expectedMultipleBars,
229 'Bar in anchor'
230 );
231
232 specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
233 expectedSpecialCharacters = $( '<a>' ).attr( {
234 title: specialCharactersPageName,
235 href: mw.util.wikiGetlink( specialCharactersPageName )
236 } ).text( specialCharactersPageName ).getOuterHtml();
237
238 mw.messages.set( 'special-characters', '[[' + specialCharactersPageName + ']]' );
239 assert.equal(
240 parser( 'special-characters' ),
241 expectedSpecialCharacters,
242 'Special characters'
243 );
244 });
245
246 QUnit.test( 'Int magic word', 4, function ( assert ) {
247 var parser = mw.jqueryMsg.getMessageFunction(),
248 newarticletextSource = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the [[{{Int:Helppage}}|help page]] for more info). If you are here by mistake, click your browser\'s back button.',
249 expectedNewarticletext;
250
251 mw.messages.set( 'helppage', 'Help:Contents' );
252
253 expectedNewarticletext = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the ' +
254 $( '<a>' ).attr( {
255 title: mw.msg( 'helppage' ),
256 href: mw.util.wikiGetlink( mw.msg( 'helppage' ) )
257 } ).text( 'help page' ).getOuterHtml() + ' for more info). If you are here by mistake, click your browser\'s back button.';
258
259 mw.messages.set( 'newarticletext', newarticletextSource );
260
261 assert.equal(
262 parser( 'newarticletext' ),
263 expectedNewarticletext,
264 'Link with nested message'
265 );
266
267 mw.messages.set( 'portal-url', 'Project:Community portal' );
268 mw.messages.set( 'see-portal-url', '{{Int:portal-url}} is an important community page.' );
269 assert.equal(
270 parser( 'see-portal-url' ),
271 'Project:Community portal is an important community page.',
272 'Nested message'
273 );
274
275 mw.messages.set( 'newarticletext-lowercase',
276 newarticletextSource.replace( 'Int:Helppage', 'int:helppage' ) );
277
278 assert.equal(
279 parser( 'newarticletext-lowercase' ),
280 expectedNewarticletext,
281 'Link with nested message, lowercase include'
282 );
283
284 mw.messages.set( 'uses-missing-int', '{{int:doesnt-exist}}' );
285
286 assert.equal(
287 parser( 'uses-missing-int' ),
288 '[doesnt-exist]',
289 'int: where nested message does not exist'
290 );
291 });
292
293 // Tests that getMessageFunction is used for messages with curly braces or square brackets,
294 // but not otherwise.
295 QUnit.test( 'Calls to mw.msg', 8, function ( assert ) {
296 // Should be
297 var map, oldGMF, outerCalled, innerCalled;
298
299 map = new mw.Map();
300 map.set( {
301 'curly-brace': '{{int:message}}',
302 'single-square-bracket': '[https://www.mediawiki.org/ MediaWiki]',
303 'double-square-bracket': '[[Some page]]',
304 'regular': 'Other message'
305 } );
306
307 oldGMF = mw.jqueryMsg.getMessageFunction;
308
309 mw.jqueryMsg.getMessageFunction = function() {
310 outerCalled = true;
311 return function() {
312 innerCalled = true;
313 };
314 };
315
316 function verifyGetMessageFunction( key, shouldCall ) {
317 outerCalled = false;
318 innerCalled = false;
319 ( new mw.Message( map, key ) ).parser();
320 assert.strictEqual( outerCalled, shouldCall, 'Outer function called for ' + key );
321 assert.strictEqual( innerCalled, shouldCall, 'Inner function called for ' + key );
322 }
323
324 verifyGetMessageFunction( 'curly-brace', true );
325 verifyGetMessageFunction( 'single-square-bracket', true );
326 verifyGetMessageFunction( 'double-square-bracket', true );
327 verifyGetMessageFunction( 'regular', false );
328
329 mw.jqueryMsg.getMessageFunction = oldGMF;
330 } );
331
332 }( mediaWiki, jQuery ) );