( function ( mw, $ ) {
- var mwLanguageCache = {}, formatText, formatParse, formatnumTests, specialCharactersPageName,
- expectedListUsers, expectedEntrypoints;
+ var formatText, formatParse, formatnumTests, specialCharactersPageName, expectedListUsers, expectedEntrypoints,
+ mwLanguageCache = {},
+ hasOwn = Object.hasOwnProperty;
// When the expected result is the same in both modes
function assertBothModes( assert, parserArguments, expectedResult, assertMessage ) {
}
} ) );
- function getMwLanguage( langCode, cb ) {
- if ( mwLanguageCache[langCode] !== undefined ) {
- mwLanguageCache[langCode].add( cb );
- return;
- }
- mwLanguageCache[langCode] = $.Callbacks( 'once memory' );
- mwLanguageCache[langCode].add( cb );
- $.ajax( {
- url: mw.util.wikiScript( 'load' ),
- data: {
- skin: mw.config.get( 'skin' ),
- lang: langCode,
- debug: mw.config.get( 'debug' ),
- modules: [
- 'mediawiki.language.data',
- 'mediawiki.language'
- ].join( '|' ),
- only: 'scripts'
- },
- dataType: 'script'
- } ).done(function () {
- mwLanguageCache[langCode].fire( mw.language );
- } ).fail( function () {
- mwLanguageCache[langCode].fire( false );
+ /**
+ * Be careful to no run this in parallel as it uses a global identifier (mw.language)
+ * to transport the module back to the test. It musn't be overwritten concurrentely.
+ *
+ * This function caches the mw.language data to avoid having to request the same module
+ * multiple times. There is more than one test case for any given language.
+ */
+ function getMwLanguage( langCode ) {
+ if ( !hasOwn.call( mwLanguageCache, langCode ) ) {
+ mwLanguageCache[langCode] = $.ajax( {
+ url: mw.util.wikiScript( 'load' ),
+ data: {
+ skin: mw.config.get( 'skin' ),
+ lang: langCode,
+ debug: mw.config.get( 'debug' ),
+ modules: [
+ 'mediawiki.language.data',
+ 'mediawiki.language'
+ ].join( '|' ),
+ only: 'scripts'
+ },
+ dataType: 'script',
+ cache: true
+ } ).then( function () {
+ return mw.language;
} );
+ }
+ return mwLanguageCache[langCode];
+ }
+
+ /**
+ * @param {Function[]} tasks List of functions that perform tasks
+ * that may be asynchronous. Invoke the callback parameter when done.
+ * @param {Function} done When all tasks are done.
+ * @return
+ */
+ function process( tasks, done ) {
+ function run() {
+ var task = tasks.shift();
+ if ( task ) {
+ task( run );
+ } else {
+ done();
+ }
+ }
+ run();
}
QUnit.test( 'Replace', 16, function ( assert ) {
QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
mw.messages.set( mw.libs.phpParserData.messages );
- $.each( mw.libs.phpParserData.tests, function ( i, test ) {
- QUnit.stop();
- getMwLanguage( test.lang, function ( langClass ) {
- QUnit.start();
- if ( !langClass ) {
- assert.ok( false, 'Language "' + test.lang + '" failed to load' );
- return;
- }
- mw.config.set( 'wgUserLanguage', test.lang );
- var parser = new mw.jqueryMsg.parser( { language: langClass } );
- assert.equal(
- parser.parse( test.key, test.args ).html(),
- test.result,
- test.name
- );
- } );
+ var tasks = $.map( mw.libs.phpParserData.tests, function ( test ) {
+ return function ( next ) {
+ getMwLanguage( test.lang )
+ .done( function ( langClass ) {
+ mw.config.set( 'wgUserLanguage', test.lang );
+ var parser = new mw.jqueryMsg.parser( { language: langClass } );
+ assert.equal(
+ parser.parse( test.key, test.args ).html(),
+ test.result,
+ test.name
+ );
+ } )
+ .fail( function () {
+ assert.ok( false, 'Language "' + test.lang + '" failed to load.' );
+ } )
+ .always( next );
+ };
} );
+
+ QUnit.stop();
+ process( tasks, QUnit.start );
} );
QUnit.test( 'Links', 6, function ( assert ) {
);
} );
-// Tests that getMessageFunction is used for non-plain messages with curly braces or
-// square brackets, but not otherwise.
+ // Tests that getMessageFunction is used for non-plain messages with curly braces or
+ // square brackets, but not otherwise.
QUnit.test( 'mw.Message.prototype.parser monkey-patch', 22, function ( assert ) {
var oldGMF, outerCalled, innerCalled;
mw.jqueryMsg.getMessageFunction = oldGMF;
} );
-formatnumTests = [
- {
- lang: 'en',
- number: 987654321.654321,
- result: '987,654,321.654',
- description: 'formatnum test for English, decimal seperator'
- },
- {
- lang: 'ar',
- number: 987654321.654321,
- result: '٩٨٧٬٦٥٤٬٣٢١٫٦٥٤',
- description: 'formatnum test for Arabic, with decimal seperator'
- },
- {
- lang: 'ar',
- number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
- result: 987654321,
- integer: true,
- description: 'formatnum test for Arabic, with decimal seperator, reverse'
- },
- {
- lang: 'ar',
- number: -12.89,
- result: '-١٢٫٨٩',
- description: 'formatnum test for Arabic, negative number'
- },
- {
- lang: 'ar',
- number: '-١٢٫٨٩',
- result: -12,
- integer: true,
- description: 'formatnum test for Arabic, negative number, reverse'
- },
- {
- lang: 'nl',
- number: 987654321.654321,
- result: '987.654.321,654',
- description: 'formatnum test for Nederlands, decimal seperator'
- },
- {
- lang: 'nl',
- number: -12.89,
- result: '-12,89',
- description: 'formatnum test for Nederlands, negative number'
- },
- {
- lang: 'nl',
- number: '.89',
- result: '0,89',
- description: 'formatnum test for Nederlands'
- },
- {
- lang: 'nl',
- number: 'invalidnumber',
- result: 'invalidnumber',
- description: 'formatnum test for Nederlands, invalid number'
- },
- {
- lang: 'ml',
- number: '1000000000',
- result: '1,00,00,00,000',
- description: 'formatnum test for Malayalam'
- },
- {
- lang: 'ml',
- number: '-1000000000',
- result: '-1,00,00,00,000',
- description: 'formatnum test for Malayalam, negative number'
- },
- /*
- * This will fail because of wrong pattern for ml in MW(different from CLDR)
- {
- lang: 'ml',
- number: '1000000000.000',
- result: '1,00,00,00,000.000',
- description: 'formatnum test for Malayalam with decimal place'
- },
- */
- {
- lang: 'hi',
- number: '123456789.123456789',
- result: '१२,३४,५६,७८९',
- description: 'formatnum test for Hindi'
- },
- {
- lang: 'hi',
- number: '१२,३४,५६,७८९',
- result: '१२,३४,५६,७८९',
- description: 'formatnum test for Hindi, Devanagari digits passed'
- },
- {
- lang: 'hi',
- number: '१२३४५६,७८९',
- result: '123456',
- integer: true,
- description: 'formatnum test for Hindi, Devanagari digits passed to get integer value'
- }
-];
-
-QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
- mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
- mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
- $.each( formatnumTests, function ( i, test ) {
- QUnit.stop();
- getMwLanguage( test.lang, function ( langClass ) {
- QUnit.start();
- if ( !langClass ) {
- assert.ok( false, 'Language "' + test.lang + '" failed to load' );
- return;
- }
- mw.messages.set(test.message );
- mw.config.set( 'wgUserLanguage', test.lang );
- var parser = new mw.jqueryMsg.parser( { language: langClass } );
- assert.equal(
- parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
- [ test.number ] ).html(),
- test.result,
- test.description
- );
+ formatnumTests = [
+ {
+ lang: 'en',
+ number: 987654321.654321,
+ result: '987,654,321.654',
+ description: 'formatnum test for English, decimal seperator'
+ },
+ {
+ lang: 'ar',
+ number: 987654321.654321,
+ result: '٩٨٧٬٦٥٤٬٣٢١٫٦٥٤',
+ description: 'formatnum test for Arabic, with decimal seperator'
+ },
+ {
+ lang: 'ar',
+ number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
+ result: 987654321,
+ integer: true,
+ description: 'formatnum test for Arabic, with decimal seperator, reverse'
+ },
+ {
+ lang: 'ar',
+ number: -12.89,
+ result: '-١٢٫٨٩',
+ description: 'formatnum test for Arabic, negative number'
+ },
+ {
+ lang: 'ar',
+ number: '-١٢٫٨٩',
+ result: -12,
+ integer: true,
+ description: 'formatnum test for Arabic, negative number, reverse'
+ },
+ {
+ lang: 'nl',
+ number: 987654321.654321,
+ result: '987.654.321,654',
+ description: 'formatnum test for Nederlands, decimal seperator'
+ },
+ {
+ lang: 'nl',
+ number: -12.89,
+ result: '-12,89',
+ description: 'formatnum test for Nederlands, negative number'
+ },
+ {
+ lang: 'nl',
+ number: '.89',
+ result: '0,89',
+ description: 'formatnum test for Nederlands'
+ },
+ {
+ lang: 'nl',
+ number: 'invalidnumber',
+ result: 'invalidnumber',
+ description: 'formatnum test for Nederlands, invalid number'
+ },
+ {
+ lang: 'ml',
+ number: '1000000000',
+ result: '1,00,00,00,000',
+ description: 'formatnum test for Malayalam'
+ },
+ {
+ lang: 'ml',
+ number: '-1000000000',
+ result: '-1,00,00,00,000',
+ description: 'formatnum test for Malayalam, negative number'
+ },
+ /*
+ * This will fail because of wrong pattern for ml in MW(different from CLDR)
+ {
+ lang: 'ml',
+ number: '1000000000.000',
+ result: '1,00,00,00,000.000',
+ description: 'formatnum test for Malayalam with decimal place'
+ },
+ */
+ {
+ lang: 'hi',
+ number: '123456789.123456789',
+ result: '१२,३४,५६,७८९',
+ description: 'formatnum test for Hindi'
+ },
+ {
+ lang: 'hi',
+ number: '१२,३४,५६,७८९',
+ result: '१२,३४,५६,७८९',
+ description: 'formatnum test for Hindi, Devanagari digits passed'
+ },
+ {
+ lang: 'hi',
+ number: '१२३४५६,७८९',
+ result: '123456',
+ integer: true,
+ description: 'formatnum test for Hindi, Devanagari digits passed to get integer value'
+ }
+ ];
+
+ QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
+ mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
+ mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
+ var queue = $.map( formatnumTests, function ( test ) {
+ return function ( next ) {
+ getMwLanguage( test.lang )
+ .done( function ( langClass ) {
+ mw.config.set( 'wgUserLanguage', test.lang );
+ var parser = new mw.jqueryMsg.parser( { language: langClass } );
+ assert.equal(
+ parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
+ [ test.number ] ).html(),
+ test.result,
+ test.description
+ );
+ } )
+ .fail( function () {
+ assert.ok( false, 'Language "' + test.lang + '" failed to load' );
+ } )
+ .always( next );
+ };
} );
+ QUnit.stop();
+ process( queue, QUnit.start );
+ } );
+
+ // HTML in wikitext
+ QUnit.test( 'HTML', 26, function ( assert ) {
+ mw.messages.set( 'jquerymsg-italics-msg', '<i>Very</i> important' );
+
+ assertBothModes( assert, ['jquerymsg-italics-msg'], mw.messages.get( 'jquerymsg-italics-msg' ), 'Simple italics unchanged' );
+
+ mw.messages.set( 'jquerymsg-bold-msg', '<b>Strong</b> speaker' );
+ assertBothModes( assert, ['jquerymsg-bold-msg'], mw.messages.get( 'jquerymsg-bold-msg' ), 'Simple bold unchanged' );
+
+ mw.messages.set( 'jquerymsg-bold-italics-msg', 'It is <b><i>key</i></b>' );
+ assertBothModes( assert, ['jquerymsg-bold-italics-msg'], mw.messages.get( 'jquerymsg-bold-italics-msg' ), 'Bold and italics nesting order preserved' );
+
+ mw.messages.set( 'jquerymsg-italics-bold-msg', 'It is <i><b>vital</b></i>' );
+ assertBothModes( assert, ['jquerymsg-italics-bold-msg'], mw.messages.get( 'jquerymsg-italics-bold-msg' ), 'Italics and bold nesting order preserved' );
+
+ mw.messages.set( 'jquerymsg-italics-with-link', 'An <i>italicized [[link|wiki-link]]</i>' );
+
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-italics-with-link' ),
+ 'An <i>italicized <a title="link" href="' + mw.html.escape( mw.util.getUrl( 'link' ) ) + '">wiki-link</i>',
+ 'Italics with link inside in parse mode'
+ );
+
+ assert.equal(
+ formatText( 'jquerymsg-italics-with-link' ),
+ mw.messages.get( 'jquerymsg-italics-with-link' ),
+ 'Italics with link unchanged in text mode'
+ );
+
+ mw.messages.set( 'jquerymsg-italics-id-class', '<i id="foo" class="bar">Foo</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-italics-id-class' ),
+ mw.messages.get( 'jquerymsg-italics-id-class' ),
+ 'ID and class are allowed'
+ );
+
+ mw.messages.set( 'jquerymsg-italics-onclick', '<i onclick="alert(\'foo\')">Foo</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-italics-onclick' ),
+ '<i onclick="alert(\'foo\')">Foo</i>',
+ 'element with onclick is escaped because it is not allowed'
+ );
+
+ mw.messages.set( 'jquerymsg-script-msg', '<script >alert( "Who put this tag here?" );</script>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-script-msg' ),
+ '<script >alert( "Who put this tag here?" );</script>',
+ 'Tag outside whitelist escaped in parse mode'
+ );
+
+ assert.equal(
+ formatText( 'jquerymsg-script-msg' ),
+ mw.messages.get( 'jquerymsg-script-msg' ),
+ 'Tag outside whitelist unchanged in text mode'
+ );
+
+ mw.messages.set( 'jquerymsg-script-link-msg', '<script>[[Foo|bar]]</script>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-script-link-msg' ),
+ '<script><a title="Foo" href="' + mw.html.escape( mw.util.getUrl( 'Foo' ) ) + '">bar</a></script>',
+ 'Script tag text is escaped because that element is not allowed, but link inside is still HTML'
+ );
+
+ mw.messages.set( 'jquerymsg-mismatched-html', '<i class="important">test</b>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-mismatched-html' ),
+ '<i class="important">test</b>',
+ 'Mismatched HTML start and end tag treated as text'
+ );
+
+ // TODO (mattflaschen, 2013-03-18): It's not a security issue, but there's no real
+ // reason the htmlEmitter span needs to be here. It's an artifact of how emitting works.
+ mw.messages.set( 'jquerymsg-script-and-external-link', '<script>alert( "jquerymsg-script-and-external-link test" );</script> [http://example.com <i>Foo</i> bar]' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-script-and-external-link' ),
+ '<script>alert( "jquerymsg-script-and-external-link test" );</script> <a href="http://example.com"><span class="mediaWiki_htmlEmitter"><i>Foo</i> bar</span></a>',
+ 'HTML tags in external links not interfering with escaping of other tags'
+ );
+
+ mw.messages.set( 'jquerymsg-link-script', '[http://example.com <script>alert( "jquerymsg-link-script test" );</script>]' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-link-script' ),
+ '<a href="http://example.com"><span class="mediaWiki_htmlEmitter"><script>alert( "jquerymsg-link-script test" );</script></span></a>',
+ 'Non-whitelisted HTML tag in external link anchor treated as text'
+ );
+
+ // Intentionally not using htmlEqual for the quote tests
+ mw.messages.set( 'jquerymsg-double-quotes-preserved', '<i id="double">Double</i>' );
+ assert.equal(
+ formatParse( 'jquerymsg-double-quotes-preserved' ),
+ mw.messages.get( 'jquerymsg-double-quotes-preserved' ),
+ 'Attributes with double quotes are preserved as such'
+ );
+
+ mw.messages.set( 'jquerymsg-single-quotes-normalized-to-double', '<i id=\'single\'>Single</i>' );
+ assert.equal(
+ formatParse( 'jquerymsg-single-quotes-normalized-to-double' ),
+ '<i id="single">Single</i>',
+ 'Attributes with single quotes are normalized to double'
+ );
+
+ mw.messages.set( 'jquerymsg-escaped-double-quotes-attribute', '<i style="font-family:"Arial"">Styled</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-escaped-double-quotes-attribute' ),
+ mw.messages.get( 'jquerymsg-escaped-double-quotes-attribute' ),
+ 'Escaped attributes are parsed correctly'
+ );
+
+ mw.messages.set( 'jquerymsg-escaped-single-quotes-attribute', '<i style=\'font-family:'Arial'\'>Styled</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-escaped-single-quotes-attribute' ),
+ mw.messages.get( 'jquerymsg-escaped-single-quotes-attribute' ),
+ 'Escaped attributes are parsed correctly'
+ );
+
+ mw.messages.set( 'jquerymsg-wikitext-contents-parsed', '<i>[http://example.com Example]</i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-wikitext-contents-parsed' ),
+ '<i><a href="http://example.com">Example</a></i>',
+ 'Contents of valid tag are treated as wikitext, so external link is parsed'
+ );
+
+ mw.messages.set( 'jquerymsg-wikitext-contents-script', '<i><script>Script inside</script></i>' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-wikitext-contents-script' ),
+ '<i><span class="mediaWiki_htmlEmitter"><script>Script inside</script></span></i>',
+ 'Contents of valid tag are treated as wikitext, so invalid HTML element is treated as text'
+ );
+
+ mw.messages.set( 'jquerymsg-unclosed-tag', 'Foo<tag>bar' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-unclosed-tag' ),
+ 'Foo<tag>bar',
+ 'Nonsupported unclosed tags are escaped'
+ );
+
+ mw.messages.set( 'jquerymsg-self-closing-tag', 'Foo<tag/>bar' );
+ assert.htmlEqual(
+ formatParse( 'jquerymsg-self-closing-tag' ),
+ 'Foo<tag/>bar',
+ 'Self-closing tags don\'t cause a parse error'
+ );
} );
-} );
-
-// HTML in wikitext
-QUnit.test( 'HTML', 26, function ( assert ) {
- mw.messages.set( 'jquerymsg-italics-msg', '<i>Very</i> important' );
-
- assertBothModes( assert, ['jquerymsg-italics-msg'], mw.messages.get( 'jquerymsg-italics-msg' ), 'Simple italics unchanged' );
-
- mw.messages.set( 'jquerymsg-bold-msg', '<b>Strong</b> speaker' );
- assertBothModes( assert, ['jquerymsg-bold-msg'], mw.messages.get( 'jquerymsg-bold-msg' ), 'Simple bold unchanged' );
-
- mw.messages.set( 'jquerymsg-bold-italics-msg', 'It is <b><i>key</i></b>' );
- assertBothModes( assert, ['jquerymsg-bold-italics-msg'], mw.messages.get( 'jquerymsg-bold-italics-msg' ), 'Bold and italics nesting order preserved' );
-
- mw.messages.set( 'jquerymsg-italics-bold-msg', 'It is <i><b>vital</b></i>' );
- assertBothModes( assert, ['jquerymsg-italics-bold-msg'], mw.messages.get( 'jquerymsg-italics-bold-msg' ), 'Italics and bold nesting order preserved' );
-
- mw.messages.set( 'jquerymsg-italics-with-link', 'An <i>italicized [[link|wiki-link]]</i>' );
-
- assert.htmlEqual(
- formatParse( 'jquerymsg-italics-with-link' ),
- 'An <i>italicized <a title="link" href="' + mw.html.escape( mw.util.getUrl( 'link' ) ) + '">wiki-link</i>',
- 'Italics with link inside in parse mode'
- );
-
- assert.equal(
- formatText( 'jquerymsg-italics-with-link' ),
- mw.messages.get( 'jquerymsg-italics-with-link' ),
- 'Italics with link unchanged in text mode'
- );
-
- mw.messages.set( 'jquerymsg-italics-id-class', '<i id="foo" class="bar">Foo</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-italics-id-class' ),
- mw.messages.get( 'jquerymsg-italics-id-class' ),
- 'ID and class are allowed'
- );
-
- mw.messages.set( 'jquerymsg-italics-onclick', '<i onclick="alert(\'foo\')">Foo</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-italics-onclick' ),
- '<i onclick="alert(\'foo\')">Foo</i>',
- 'element with onclick is escaped because it is not allowed'
- );
-
- mw.messages.set( 'jquerymsg-script-msg', '<script >alert( "Who put this tag here?" );</script>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-script-msg' ),
- '<script >alert( "Who put this tag here?" );</script>',
- 'Tag outside whitelist escaped in parse mode'
- );
-
- assert.equal(
- formatText( 'jquerymsg-script-msg' ),
- mw.messages.get( 'jquerymsg-script-msg' ),
- 'Tag outside whitelist unchanged in text mode'
- );
-
- mw.messages.set( 'jquerymsg-script-link-msg', '<script>[[Foo|bar]]</script>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-script-link-msg' ),
- '<script><a title="Foo" href="' + mw.html.escape( mw.util.getUrl( 'Foo' ) ) + '">bar</a></script>',
- 'Script tag text is escaped because that element is not allowed, but link inside is still HTML'
- );
-
- mw.messages.set( 'jquerymsg-mismatched-html', '<i class="important">test</b>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-mismatched-html' ),
- '<i class="important">test</b>',
- 'Mismatched HTML start and end tag treated as text'
- );
-
- // TODO (mattflaschen, 2013-03-18): It's not a security issue, but there's no real
- // reason the htmlEmitter span needs to be here. It's an artifact of how emitting works.
- mw.messages.set( 'jquerymsg-script-and-external-link', '<script>alert( "jquerymsg-script-and-external-link test" );</script> [http://example.com <i>Foo</i> bar]' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-script-and-external-link' ),
- '<script>alert( "jquerymsg-script-and-external-link test" );</script> <a href="http://example.com"><span class="mediaWiki_htmlEmitter"><i>Foo</i> bar</span></a>',
- 'HTML tags in external links not interfering with escaping of other tags'
- );
-
- mw.messages.set( 'jquerymsg-link-script', '[http://example.com <script>alert( "jquerymsg-link-script test" );</script>]' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-link-script' ),
- '<a href="http://example.com"><span class="mediaWiki_htmlEmitter"><script>alert( "jquerymsg-link-script test" );</script></span></a>',
- 'Non-whitelisted HTML tag in external link anchor treated as text'
- );
-
- // Intentionally not using htmlEqual for the quote tests
- mw.messages.set( 'jquerymsg-double-quotes-preserved', '<i id="double">Double</i>' );
- assert.equal(
- formatParse( 'jquerymsg-double-quotes-preserved' ),
- mw.messages.get( 'jquerymsg-double-quotes-preserved' ),
- 'Attributes with double quotes are preserved as such'
- );
-
- mw.messages.set( 'jquerymsg-single-quotes-normalized-to-double', '<i id=\'single\'>Single</i>' );
- assert.equal(
- formatParse( 'jquerymsg-single-quotes-normalized-to-double' ),
- '<i id="single">Single</i>',
- 'Attributes with single quotes are normalized to double'
- );
-
- mw.messages.set( 'jquerymsg-escaped-double-quotes-attribute', '<i style="font-family:"Arial"">Styled</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-escaped-double-quotes-attribute' ),
- mw.messages.get( 'jquerymsg-escaped-double-quotes-attribute' ),
- 'Escaped attributes are parsed correctly'
- );
-
- mw.messages.set( 'jquerymsg-escaped-single-quotes-attribute', '<i style=\'font-family:'Arial'\'>Styled</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-escaped-single-quotes-attribute' ),
- mw.messages.get( 'jquerymsg-escaped-single-quotes-attribute' ),
- 'Escaped attributes are parsed correctly'
- );
-
- mw.messages.set( 'jquerymsg-wikitext-contents-parsed', '<i>[http://example.com Example]</i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-wikitext-contents-parsed' ),
- '<i><a href="http://example.com">Example</a></i>',
- 'Contents of valid tag are treated as wikitext, so external link is parsed'
- );
-
- mw.messages.set( 'jquerymsg-wikitext-contents-script', '<i><script>Script inside</script></i>' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-wikitext-contents-script' ),
- '<i><span class="mediaWiki_htmlEmitter"><script>Script inside</script></span></i>',
- 'Contents of valid tag are treated as wikitext, so invalid HTML element is treated as text'
- );
-
- mw.messages.set( 'jquerymsg-unclosed-tag', 'Foo<tag>bar' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-unclosed-tag' ),
- 'Foo<tag>bar',
- 'Nonsupported unclosed tags are escaped'
- );
-
- mw.messages.set( 'jquerymsg-self-closing-tag', 'Foo<tag/>bar' );
- assert.htmlEqual(
- formatParse( 'jquerymsg-self-closing-tag' ),
- 'Foo<tag/>bar',
- 'Self-closing tags don\'t cause a parse error'
- );
-} );
QUnit.test( 'Behavior in case of invalid wikitext', 3, function ( assert ) {
mw.messages.set( 'invalid-wikitext', '<b>{{FAIL}}</b>' );