3 var mwLanguageCache
= {}, oldGetOuterHtml
;
5 QUnit
.module( 'mediawiki.jqueryMsg', QUnit
.newMwEnvironment( {
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() );
19 teardown: function () {
20 mw
.language
= this.orgMwLangauge
;
21 $.fn
.getOuterHtml
= oldGetOuterHtml
;
25 function getMwLanguage( langCode
, cb
) {
26 if ( mwLanguageCache
[langCode
] !== undefined ) {
27 mwLanguageCache
[langCode
].add( cb
);
30 mwLanguageCache
[langCode
] = $.Callbacks( 'once memory' );
31 mwLanguageCache
[langCode
].add( cb
);
33 url
: mw
.util
.wikiScript( 'load' ),
35 skin
: mw
.config
.get( 'skin' ),
37 debug
: mw
.config
.get( 'debug' ),
39 'mediawiki.language.data',
45 }).done( function () {
46 mwLanguageCache
[langCode
].fire( mw
.language
);
47 }).fail( function () {
48 mwLanguageCache
[langCode
].fire( false );
52 QUnit
.test( 'Plural', 3, function ( assert
) {
53 var parser
= mw
.jqueryMsg
.getMessageFunction();
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' );
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
66 parser
= mw
.jqueryMsg
.getMessageFunction();
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}}' );
72 user
.options
.set( 'gender', 'male' );
74 parser( 'gender-msg', 'Bob', 'male' ),
76 'Masculine from string "male"'
79 parser( 'gender-msg', 'Bob', user
),
81 'Masculine from mw.user object'
84 user
.options
.set( 'gender', 'unknown' );
86 parser( 'gender-msg', 'Foo', user
),
88 'Neutral from mw.user object' );
90 parser( 'gender-msg', 'Alice', 'female' ),
92 'Feminine from string "female"' );
94 parser( 'gender-msg', 'User' ),
96 'Neutral when no parameter given' );
98 parser( 'gender-msg', 'User', 'unknown' ),
100 'Neutral from string "unknown"'
103 mw
.messages
.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
106 parser( 'gender-msg-one-form', 'male', 10 ),
108 'Gender neutral and plural form'
111 parser( 'gender-msg-one-form', 'female', 1 ),
113 'Gender neutral and singular form'
116 mw
.messages
.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' );
118 parser( 'gender-msg-lowercase', 'male' ),
123 parser( 'gender-msg-lowercase', 'female' ),
128 mw
.messages
.set( 'gender-msg-wrong', '{{gender}} test' );
130 parser( 'gender-msg-wrong', 'female' ),
132 'Invalid syntax should result in {{gender}} simply being stripped away'
136 QUnit
.test( 'Grammar', 2, function ( assert
) {
137 var parser
= mw
.jqueryMsg
.getMessageFunction();
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' );
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' );
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
) {
151 getMwLanguage( test
.lang
, function ( langClass
) {
154 assert
.ok( false, 'Language "' + test
.lang
+ '" failed to load' );
157 mw
.config
.set( 'wgUserLanguage', test
.lang
) ;
158 var parser
= new mw
.jqueryMsg
.parser( { language
: langClass
} );
160 parser
.parse( test
.key
, test
.args
).html(),
168 QUnit
.test( 'Links', 6, function ( assert
) {
169 var parser
= mw
.jqueryMsg
.getMessageFunction(),
171 expectedDisambiguationsText
,
172 expectedMultipleBars
,
173 expectedSpecialCharacters
,
174 specialCharactersPageName
;
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.
181 mw
.messages
.set( 'statistics-users', '注册[[Special:ListUsers|用户]]' );
183 expectedListUsers
= '注册' + $( '<a>' ).attr( {
184 title
: 'Special:ListUsers',
185 href
: mw
.util
.wikiGetlink( 'Special:ListUsers' )
186 } ).text( '用户' ).getOuterHtml();
189 parser( 'statistics-users' ),
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 ' +
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]].' );
201 parser( 'disambiguations-text' ),
202 expectedDisambiguationsText
,
203 'Wikilink without pipe'
206 mw
.messages
.set( 'version-entrypoints-index-php', '[https://www.mediawiki.org/wiki/Manual:index.php index.php]' );
208 parser( 'version-entrypoints-index-php' ),
209 '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>',
213 // Pipe trick is not supported currently, but should not parse as text either.
214 mw
.messages
.set( 'pipe-trick', '[[Tampa, Florida|]]' );
216 parser( 'pipe-trick' ),
217 'pipe-trick: Parse error at position 0 in input: [[Tampa, Florida|]]',
218 'Pipe trick should return error string.'
221 expectedMultipleBars
= $( '<a>' ).attr( {
223 href
: mw
.util
.wikiGetlink( 'Main Page' )
224 } ).text( 'Main|Page' ).getOuterHtml();
225 mw
.messages
.set( 'multiple-bars', '[[Main Page|Main|Page]]' );
227 parser( 'multiple-bars' ),
228 expectedMultipleBars
,
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();
238 mw
.messages
.set( 'special-characters', '[[' + specialCharactersPageName
+ ']]' );
240 parser( 'special-characters' ),
241 expectedSpecialCharacters
,
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
;
251 mw
.messages
.set( 'helppage', 'Help:Contents' );
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 ' +
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.';
259 mw
.messages
.set( 'newarticletext', newarticletextSource
);
262 parser( 'newarticletext' ),
263 expectedNewarticletext
,
264 'Link with nested message'
267 mw
.messages
.set( 'portal-url', 'Project:Community portal' );
268 mw
.messages
.set( 'see-portal-url', '{{Int:portal-url}} is an important community page.' );
270 parser( 'see-portal-url' ),
271 'Project:Community portal is an important community page.',
275 mw
.messages
.set( 'newarticletext-lowercase',
276 newarticletextSource
.replace( 'Int:Helppage', 'int:helppage' ) );
279 parser( 'newarticletext-lowercase' ),
280 expectedNewarticletext
,
281 'Link with nested message, lowercase include'
284 mw
.messages
.set( 'uses-missing-int', '{{int:doesnt-exist}}' );
287 parser( 'uses-missing-int' ),
289 'int: where nested message does not exist'
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
) {
297 var map
, oldGMF
, outerCalled
, innerCalled
;
301 'curly-brace': '{{int:message}}',
302 'single-square-bracket': '[https://www.mediawiki.org/ MediaWiki]',
303 'double-square-bracket': '[[Some page]]',
304 'regular': 'Other message'
307 oldGMF
= mw
.jqueryMsg
.getMessageFunction
;
309 mw
.jqueryMsg
.getMessageFunction = function() {
316 function verifyGetMessageFunction( key
, shouldCall
) {
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
);
324 verifyGetMessageFunction( 'curly-brace', true );
325 verifyGetMessageFunction( 'single-square-bracket', true );
326 verifyGetMessageFunction( 'double-square-bracket', true );
327 verifyGetMessageFunction( 'regular', false );
329 mw
.jqueryMsg
.getMessageFunction
= oldGMF
;
332 }( mediaWiki
, jQuery
) );