summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2015-12-17 09:15:42 +0100
committerPierre Schmitz <pierre@archlinux.de>2015-12-17 09:44:51 +0100
commita1789ddde42033f1b05cc4929491214ee6e79383 (patch)
tree63615735c4ddffaaabf2428946bb26f90899f7bf /tests
parent9e06a62f265e3a2aaabecc598d4bc617e06fa32d (diff)
Update to MediaWiki 1.26.0
Diffstat (limited to 'tests')
-rw-r--r--tests/TestsAutoLoader.php13
-rw-r--r--tests/browser/environments.yml4
-rw-r--r--tests/browser/features/create_account.feature5
-rw-r--r--tests/browser/features/step_definitions/create_account_steps.rb8
-rw-r--r--tests/browser/features/support/pages/create_account_page.rb1
-rw-r--r--tests/browser/features/support/pages/main_page.rb6
-rw-r--r--tests/browser/features/support/pages/preferences_appearance_page.rb2
-rw-r--r--tests/browser/features/support/pages/view_history_page.rb4
-rw-r--r--tests/parser/parserTest.inc9
-rw-r--r--tests/parser/parserTests.txt4253
-rw-r--r--tests/parser/preprocess/All_system_messages.expected6
-rw-r--r--tests/parser/preprocess/All_system_messages.txt6
-rw-r--r--tests/parserTests.php2
-rw-r--r--tests/phpunit/LessFileCompilationTest.php6
-rw-r--r--tests/phpunit/Makefile1
-rw-r--r--tests/phpunit/MediaWikiTestCase.php30
-rw-r--r--tests/phpunit/README17
-rw-r--r--tests/phpunit/ResourceLoaderTestCase.php44
-rw-r--r--tests/phpunit/data/css/comments.css7
-rw-r--r--tests/phpunit/data/helpers/WellProtectedClass.php29
-rw-r--r--tests/phpunit/data/import/ImportLinkCacheIntegrationTest.xml43
-rw-r--r--tests/phpunit/data/less/common/test.common.mixins.less1
-rw-r--r--tests/phpunit/data/less/module/styles.css3
-rw-r--r--tests/phpunit/data/media/2_webp_a.webpbin0 -> 17128 bytes
-rw-r--r--tests/phpunit/data/media/2_webp_ll.webpbin0 -> 29360 bytes
-rw-r--r--tests/phpunit/data/media/srgb.jpgbin0 -> 7738 bytes
-rw-r--r--tests/phpunit/data/media/tinyrgb.iccbin0 -> 524 bytes
-rw-r--r--tests/phpunit/data/media/tinyrgb.jpgbin0 -> 5118 bytes
-rw-r--r--tests/phpunit/data/media/webp_animated.webpbin0 -> 380850 bytes
-rw-r--r--tests/phpunit/data/templates/bad_partial.mustache1
-rw-r--r--tests/phpunit/data/templates/has_partial.mustache1
-rw-r--r--tests/phpunit/includes/BlockTest.php114
-rw-r--r--tests/phpunit/includes/ConsecutiveParametersMatcher.php123
-rw-r--r--tests/phpunit/includes/EditPageTest.php55
-rw-r--r--tests/phpunit/includes/ExtraParserTest.php3
-rw-r--r--tests/phpunit/includes/FauxRequestTest.php43
-rw-r--r--tests/phpunit/includes/FauxResponseTest.php7
-rw-r--r--tests/phpunit/includes/GlobalFunctions/GlobalTest.php103
-rw-r--r--tests/phpunit/includes/GlobalFunctions/wfArrayPlus2dTest.php94
-rw-r--r--tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php1
-rw-r--r--tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php2
-rw-r--r--tests/phpunit/includes/ImportLinkCacheIntegrationTest.php112
-rw-r--r--tests/phpunit/includes/LinkFilterTest.php12
-rw-r--r--tests/phpunit/includes/LinkerTest.php66
-rw-r--r--tests/phpunit/includes/MediaWikiTest.php157
-rw-r--r--tests/phpunit/includes/MessageTest.php33
-rw-r--r--tests/phpunit/includes/MimeMagicTest.php2
-rw-r--r--tests/phpunit/includes/MovePageTest.php2
-rw-r--r--tests/phpunit/includes/OutputPageTest.php168
-rw-r--r--tests/phpunit/includes/PrefixSearchTest.php5
-rw-r--r--tests/phpunit/includes/SanitizerTest.php12
-rw-r--r--tests/phpunit/includes/SanitizerValidateEmailTest.php2
-rw-r--r--tests/phpunit/includes/StatusTest.php4
-rw-r--r--tests/phpunit/includes/TemplateParserTest.php15
-rw-r--r--tests/phpunit/includes/TestingAccessWrapper.php34
-rw-r--r--tests/phpunit/includes/TestingAccessWrapperTest.php18
-rw-r--r--tests/phpunit/includes/TitleArrayFromResultTest.php2
-rw-r--r--tests/phpunit/includes/TitlePermissionTest.php22
-rw-r--r--tests/phpunit/includes/TitleTest.php101
-rw-r--r--tests/phpunit/includes/UserTest.php130
-rw-r--r--tests/phpunit/includes/WikiMapTest.php108
-rw-r--r--tests/phpunit/includes/WikiReferenceTest.php80
-rw-r--r--tests/phpunit/includes/XmlJsTest.php2
-rw-r--r--tests/phpunit/includes/XmlTest.php6
-rw-r--r--tests/phpunit/includes/api/ApiBlockTest.php6
-rw-r--r--tests/phpunit/includes/api/ApiEditPageTest.php113
-rw-r--r--tests/phpunit/includes/api/ApiLoginTest.php4
-rw-r--r--tests/phpunit/includes/api/ApiMainTest.php171
-rw-r--r--tests/phpunit/includes/api/ApiMessageTest.php20
-rw-r--r--tests/phpunit/includes/api/ApiQueryAllPagesTest.php6
-rw-r--r--tests/phpunit/includes/api/ApiResultTest.php194
-rw-r--r--tests/phpunit/includes/api/ApiRevisionDeleteTest.php4
-rw-r--r--tests/phpunit/includes/api/ApiTestCase.php1
-rw-r--r--tests/phpunit/includes/api/ApiUnblockTest.php4
-rw-r--r--tests/phpunit/includes/api/ApiUploadTest.php36
-rw-r--r--tests/phpunit/includes/api/format/ApiFormatDumpTest.php63
-rw-r--r--tests/phpunit/includes/api/format/ApiFormatWddxTest.php80
-rw-r--r--tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php5
-rw-r--r--tests/phpunit/includes/api/query/ApiQueryTest.php2
-rw-r--r--tests/phpunit/includes/api/query/ApiQueryTestBase.php14
-rw-r--r--tests/phpunit/includes/cache/MessageCacheTest.php29
-rw-r--r--tests/phpunit/includes/changes/RecentChangeTest.php327
-rw-r--r--tests/phpunit/includes/config/HashConfigTest.php2
-rw-r--r--tests/phpunit/includes/content/ContentHandlerTest.php179
-rw-r--r--tests/phpunit/includes/content/CssContentHandlerTest.php30
-rw-r--r--tests/phpunit/includes/content/CssContentTest.php45
-rw-r--r--tests/phpunit/includes/content/JavaScriptContentHandlerTest.php30
-rw-r--r--tests/phpunit/includes/content/JavaScriptContentTest.php53
-rw-r--r--tests/phpunit/includes/content/JsonContentTest.php2
-rw-r--r--tests/phpunit/includes/content/TextContentHandlerTest.php12
-rw-r--r--tests/phpunit/includes/content/TextContentTest.php8
-rw-r--r--tests/phpunit/includes/content/WikitextContentHandlerTest.php5
-rw-r--r--tests/phpunit/includes/db/DatabaseMysqlBaseTest.php2
-rw-r--r--tests/phpunit/includes/db/DatabaseSqliteTest.php25
-rw-r--r--tests/phpunit/includes/db/ORMTableTest.php19
-rw-r--r--tests/phpunit/includes/debug/MWDebugTest.php4
-rw-r--r--tests/phpunit/includes/debug/logger/LegacyLoggerTest.php (renamed from tests/phpunit/includes/debug/logging/LegacyLoggerTest.php)53
-rw-r--r--tests/phpunit/includes/debug/logger/MonologSpiTest.php136
-rw-r--r--tests/phpunit/includes/debug/logger/monolog/AvroFormatterTest.php64
-rw-r--r--tests/phpunit/includes/debug/logger/monolog/KafkaHandlerTest.php207
-rw-r--r--tests/phpunit/includes/debug/logger/monolog/LineFormatterTest.php75
-rw-r--r--tests/phpunit/includes/deferred/DeferredUpdatesTest.php37
-rw-r--r--tests/phpunit/includes/diff/ArrayDiffFormatterTest.php4
-rw-r--r--tests/phpunit/includes/exception/HttpErrorTest.php65
-rw-r--r--tests/phpunit/includes/exception/MWExceptionTest.php2
-rw-r--r--tests/phpunit/includes/filebackend/FileBackendTest.php52
-rw-r--r--tests/phpunit/includes/filebackend/SwiftFileBackendTest.php148
-rw-r--r--tests/phpunit/includes/filerepo/FileBackendDBRepoWrapperTest.php138
-rw-r--r--tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php114
-rw-r--r--tests/phpunit/includes/htmlform/HTMLAutoCompleteSelectFieldTest.php2
-rw-r--r--tests/phpunit/includes/json/FormatJsonTest.php10
-rw-r--r--tests/phpunit/includes/libs/ArrayUtilsTest.php12
-rw-r--r--tests/phpunit/includes/libs/CSSMinTest.php57
-rw-r--r--tests/phpunit/includes/libs/IEUrlExtensionTest.php33
-rw-r--r--tests/phpunit/includes/libs/IPSetTest.php252
-rw-r--r--tests/phpunit/includes/libs/JavaScriptMinifierTest.php19
-rw-r--r--tests/phpunit/includes/libs/ObjectFactoryTest.php41
-rw-r--r--tests/phpunit/includes/libs/ProcessCacheLRUTest.php2
-rw-r--r--tests/phpunit/includes/libs/SamplingStatsdClientTest.php43
-rw-r--r--tests/phpunit/includes/libs/XhprofTest.php16
-rw-r--r--tests/phpunit/includes/libs/composer/ComposerLockTest.php61
-rw-r--r--tests/phpunit/includes/logging/BlockLogFormatterTest.php372
-rw-r--r--tests/phpunit/includes/logging/DeleteLogFormatterTest.php527
-rw-r--r--tests/phpunit/includes/logging/LogFormatterTest.php321
-rw-r--r--tests/phpunit/includes/logging/LogFormatterTestCase.php65
-rw-r--r--tests/phpunit/includes/logging/MergeLogFormatterTest.php67
-rw-r--r--tests/phpunit/includes/logging/MoveLogFormatterTest.php270
-rw-r--r--tests/phpunit/includes/logging/NewUsersLogFormatterTest.php207
-rw-r--r--tests/phpunit/includes/logging/PageLangLogFormatterTest.php53
-rw-r--r--tests/phpunit/includes/logging/PatrolLogFormatterTest.php118
-rw-r--r--tests/phpunit/includes/logging/ProtectLogFormatterTest.php63
-rw-r--r--tests/phpunit/includes/logging/RightsLogFormatterTest.php157
-rw-r--r--tests/phpunit/includes/logging/UploadLogFormatterTest.php166
-rw-r--r--tests/phpunit/includes/media/ExifBitmapTest.php39
-rw-r--r--tests/phpunit/includes/media/FormatMetadataTest.php33
-rw-r--r--tests/phpunit/includes/media/WebPTest.php127
-rw-r--r--tests/phpunit/includes/media/XMPValidateTest.php5
-rw-r--r--tests/phpunit/includes/objectcache/BagOStuffTest.php34
-rw-r--r--tests/phpunit/includes/objectcache/MultiWriteBagOStuffTest.php55
-rw-r--r--tests/phpunit/includes/objectcache/ReplicatedBagOStuffTest.php62
-rw-r--r--tests/phpunit/includes/objectcache/WANObjectCacheTest.php292
-rw-r--r--tests/phpunit/includes/parser/MagicVariableTest.php2
-rw-r--r--tests/phpunit/includes/parser/MediaWikiParserTest.php2
-rw-r--r--tests/phpunit/includes/parser/NewParserTest.php10
-rw-r--r--tests/phpunit/includes/parser/ParserMethodsTest.php4
-rw-r--r--tests/phpunit/includes/parser/TagHooksTest.php7
-rw-r--r--tests/phpunit/includes/parser/TidyTest.php3
-rw-r--r--tests/phpunit/includes/password/PasswordPolicyChecksTest.php136
-rw-r--r--tests/phpunit/includes/password/UserPasswordPolicyTest.php234
-rw-r--r--tests/phpunit/includes/registration/CoreVersionCheckerTest.php38
-rw-r--r--tests/phpunit/includes/registration/ExtensionProcessorTest.php16
-rw-r--r--tests/phpunit/includes/registration/ExtensionRegistryTest.php2
-rw-r--r--tests/phpunit/includes/resourceloader/DerivativeResourceLoaderContextTest.php78
-rw-r--r--tests/phpunit/includes/resourceloader/ResourceLoaderFileModuleTest.php22
-rw-r--r--tests/phpunit/includes/resourceloader/ResourceLoaderImageTest.php3
-rw-r--r--tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php58
-rw-r--r--tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php74
-rw-r--r--tests/phpunit/includes/resourceloader/ResourceLoaderTest.php11
-rw-r--r--tests/phpunit/includes/resourceloader/ResourceLoaderWikiModuleTest.php49
-rw-r--r--tests/phpunit/includes/site/CachingSiteStoreTest.php8
-rw-r--r--tests/phpunit/includes/site/DBSiteStoreTest.php24
-rw-r--r--tests/phpunit/includes/site/HashSiteStoreTest.php2
-rw-r--r--tests/phpunit/includes/site/SiteExporterTest.php4
-rw-r--r--tests/phpunit/includes/site/SiteImporterTest.php12
-rw-r--r--tests/phpunit/includes/specials/SpecialBlankPageTest.php25
-rw-r--r--tests/phpunit/includes/specials/SpecialPageTestBase.php165
-rw-r--r--tests/phpunit/includes/specials/SpecialPreferencesTest.php3
-rw-r--r--tests/phpunit/includes/specials/SpecialSearchTest.php106
-rw-r--r--tests/phpunit/includes/title/ForeignTitleTest.php4
-rw-r--r--tests/phpunit/includes/title/MediaWikiPageLinkRendererTest.php2
-rw-r--r--tests/phpunit/includes/upload/UploadStashTest.php2
-rw-r--r--tests/phpunit/includes/utils/AvroValidatorTest.php96
-rw-r--r--tests/phpunit/includes/utils/BatchRowUpdateTest.php243
-rw-r--r--tests/phpunit/includes/utils/IPTest.php273
-rw-r--r--tests/phpunit/includes/utils/MWFunctionTest.php34
-rw-r--r--tests/phpunit/includes/utils/UIDGeneratorTest.php10
-rw-r--r--tests/phpunit/languages/LanguageTest.php100
-rw-r--r--tests/phpunit/languages/classes/LanguageArqTest.php2
-rw-r--r--tests/phpunit/maintenance/backupTextPassTest.php8
-rw-r--r--tests/phpunit/mocks/MockWebRequest.php26
-rw-r--r--tests/phpunit/mocks/content/DummyContentForTesting.php121
-rw-r--r--tests/phpunit/mocks/content/DummyContentHandlerForTesting.php42
-rw-r--r--tests/phpunit/mocks/content/DummyNonTextContent.php121
-rw-r--r--tests/phpunit/mocks/content/DummyNonTextContentHandler.php46
-rw-r--r--tests/phpunit/phpunit.php35
-rw-r--r--tests/phpunit/structure/AutoLoaderTest.php4
-rw-r--r--tests/phpunit/structure/AvailableRightsTest.php4
-rw-r--r--tests/phpunit/structure/ResourcesTest.php52
-rw-r--r--tests/phpunit/suites/UploadFromUrlTestSuite.php4
-rw-r--r--tests/qunit/QUnitTestResources.php15
-rw-r--r--tests/qunit/data/generateJqueryMsgData.php3
-rw-r--r--tests/qunit/data/mediawiki.jqueryMsg.data.js3
-rw-r--r--tests/qunit/data/testrunner.js99
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.accessKeyLabel.test.js40
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js4
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.color.test.js2
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js36
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.hidpi.test.js16
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.localize.test.js14
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js18
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js15
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.placeholder.test.js172
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.tablesorter.parsers.test.js220
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js413
-rw-r--r--tests/qunit/suites/resources/jquery/jquery.textSelection.test.js33
-rw-r--r--tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js39
-rw-r--r--tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js346
-rw-r--r--tests/qunit/suites/resources/mediawiki.api/mediawiki.api.upload.test.js35
-rw-r--r--tests/qunit/suites/resources/mediawiki.api/mediawiki.api.watch.test.js6
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.RegExp.test.js38
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js171
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js10
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js6
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js4
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.errorLogger.test.js2
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.experiments.test.js63
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js269
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js2
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js14
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.messagePoster.factory.test.js2
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.storage.test.js36
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.test.js283
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.toc.test.js2
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.track.test.js18
-rw-r--r--tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js127
-rw-r--r--tests/qunit/suites/resources/startup.test.js4
-rw-r--r--tests/testHelpers.inc2
227 files changed, 13620 insertions, 3600 deletions
diff --git a/tests/TestsAutoLoader.php b/tests/TestsAutoLoader.php
index def23dad..8a81a644 100644
--- a/tests/TestsAutoLoader.php
+++ b/tests/TestsAutoLoader.php
@@ -66,8 +66,10 @@ $wgAutoloadClasses += array(
'TestRecentChangesHelper' => "$testDir/phpunit/includes/changes/TestRecentChangesHelper.php",
# tests/phpunit/includes/content
- 'DummyContentHandlerForTesting' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
- 'DummyContentForTesting' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
+ 'DummyContentHandlerForTesting' => "$testDir/phpunit/mocks/content/DummyContentHandlerForTesting.php",
+ 'DummyContentForTesting' => "$testDir/phpunit/mocks/content/DummyContentForTesting.php",
+ 'DummyNonTextContentHandler' => "$testDir/phpunit/mocks/content/DummyNonTextContentHandler.php",
+ 'DummyNonTextContent' => "$testDir/phpunit/mocks/content/DummyNonTextContent.php",
'ContentHandlerTest' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
'JavaScriptContentTest' => "$testDir/phpunit/includes/content/JavaScriptContentTest.php",
'TextContentTest' => "$testDir/phpunit/includes/content/TextContentTest.php",
@@ -82,6 +84,9 @@ $wgAutoloadClasses += array(
# tests/phpunit/includes/diff
'FakeDiffOp' => "$testDir/phpunit/includes/diff/FakeDiffOp.php",
+ # tests/phpunit/includes/logging
+ 'LogFormatterTestCase' => "$testDir/phpunit/includes/logging/LogFormatterTestCase.php",
+
# tests/phpunit/includes/password
'PasswordTestCase' => "$testDir/phpunit/includes/password/PasswordTestCase.php",
@@ -89,6 +94,9 @@ $wgAutoloadClasses += array(
'ResourceLoaderImageModuleTest' => "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
'ResourceLoaderImageModuleTestable' => "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
+ # tests/phpunit/includes/specials
+ 'SpecialPageTestBase' => "$testDir/phpunit/includes/specials/SpecialPageTestBase.php",
+
# tests/phpunit/languages
'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",
@@ -109,6 +117,7 @@ $wgAutoloadClasses += array(
'MockImageHandler' => "$testDir/phpunit/mocks/media/MockImageHandler.php",
'MockSvgHandler' => "$testDir/phpunit/mocks/media/MockSvgHandler.php",
'MockDjVuHandler' => "$testDir/phpunit/mocks/media/MockDjVuHandler.php",
+ 'MockWebRequest' => "$testDir/phpunit/mocks/MockWebRequest.php",
# tests/parser
'NewParserTest' => "$testDir/phpunit/includes/parser/NewParserTest.php",
diff --git a/tests/browser/environments.yml b/tests/browser/environments.yml
index 8f8381ed..b2232e62 100644
--- a/tests/browser/environments.yml
+++ b/tests/browser/environments.yml
@@ -14,7 +14,7 @@
# export MEDIAWIKI_USER=Selenium_user2
# bundle exec cucumber
#
-mw-vagrant-host:
+mw-vagrant-host: &default
mediawiki_url: http://127.0.0.1:8080/wiki/
mediawiki_user: Selenium_user
mediawiki_password: vagrant
@@ -33,3 +33,5 @@ test2:
mediawiki_url: http://test2.wikipedia.org/wiki/
mediawiki_user: Selenium_user
# mediawiki_password: SET THIS IN THE ENVIRONMENT!
+
+default: *default
diff --git a/tests/browser/features/create_account.feature b/tests/browser/features/create_account.feature
index 0b4e83a5..35df8b4b 100644
--- a/tests/browser/features/create_account.feature
+++ b/tests/browser/features/create_account.feature
@@ -10,3 +10,8 @@ Feature: Create account
| Special:CreateAccount |
| Special:UserLogin/signup |
| Special:UserLogin?type=signup |
+
+ Scenario: If no username is entered then an error is displayed
+ Given I go to Create account page at Special:CreateAccount
+ When I submit the form
+ Then an error message is displayed
diff --git a/tests/browser/features/step_definitions/create_account_steps.rb b/tests/browser/features/step_definitions/create_account_steps.rb
index 03bff66f..98e0f2cb 100644
--- a/tests/browser/features/step_definitions/create_account_steps.rb
+++ b/tests/browser/features/step_definitions/create_account_steps.rb
@@ -16,3 +16,11 @@ end
Then(/^form has Create account button$/) do
expect(on(CreateAccountPage).create_account_element).to exist
end
+
+When(/^I submit the form$/) do
+ on(CreateAccountPage).create_account
+end
+
+Then(/^an error message is displayed$/) do
+ expect(on(CreateAccountPage).error_message_element.class_name).to eq 'errorbox'
+end
diff --git a/tests/browser/features/support/pages/create_account_page.rb b/tests/browser/features/support/pages/create_account_page.rb
index 98b893a6..9aa00cd2 100644
--- a/tests/browser/features/support/pages/create_account_page.rb
+++ b/tests/browser/features/support/pages/create_account_page.rb
@@ -15,4 +15,5 @@ class CreateAccountPage
page_url '<%=params[:page_title]%>'
button(:create_account, id: 'wpCreateaccount')
+ div(:error_message, id: 'mw-createacct-status-area')
end
diff --git a/tests/browser/features/support/pages/main_page.rb b/tests/browser/features/support/pages/main_page.rb
index 6d76b01c..3092ab5c 100644
--- a/tests/browser/features/support/pages/main_page.rb
+++ b/tests/browser/features/support/pages/main_page.rb
@@ -3,16 +3,16 @@ class MainPage
page_url ''
- a(:edit_link, href: /action=edit/)
+ a(:edit_link, css: '#ca-edit a')
li(:help_link, id: 'n-help')
div(:page_content, id: 'content')
li(:page_information_link, id: 't-info')
li(:permanent_link_link, id: 't-permalink')
- a(:printable_version_link, href: /printable=yes/)
+ a(:printable_version_link, css: '#t-print a')
li(:random_page_link, id: 'n-randompage')
li(:recent_changes_link, id: 'n-recentchanges')
li(:related_changes_link, id: 't-recentchangeslinked')
li(:special_pages_link, id: 't-specialpages')
- a(:view_history_link, href: /action=history/)
+ a(:view_history_link, css: '#ca-history a')
li(:what_links_here_link, id: 't-whatlinkshere')
end
diff --git a/tests/browser/features/support/pages/preferences_appearance_page.rb b/tests/browser/features/support/pages/preferences_appearance_page.rb
index 83c3952f..1e5ffaa1 100644
--- a/tests/browser/features/support/pages/preferences_appearance_page.rb
+++ b/tests/browser/features/support/pages/preferences_appearance_page.rb
@@ -27,7 +27,7 @@ class PreferencesAppearancePage
radio_button(:monobook, id: 'mw-input-wpskin-monobook')
radio_button(:no_preference_radio, id: 'mw-input-wpdate-default')
text_field(:other_offset, id: 'mw-input-wptimecorrection-other')
- a(:restore_default_link, href: /reset/)
+ a(:restore_default_link, id: 'mw-prefs-restoreprefs')
select_list(:size_select, id: 'mw-input-wpimagesize')
select_list(:threshold_select, id: 'mw-input-wpstubthreshold')
select_list(:time_offset_select, id: 'mw-input-wptimecorrection')
diff --git a/tests/browser/features/support/pages/view_history_page.rb b/tests/browser/features/support/pages/view_history_page.rb
index bb9c5862..ee4d757a 100644
--- a/tests/browser/features/support/pages/view_history_page.rb
+++ b/tests/browser/features/support/pages/view_history_page.rb
@@ -1,6 +1,6 @@
class ViewHistoryPage
include PageObject
- a(:view_history_link, href: /action=history/)
- a(:old_version_link, href: /oldid=/)
+ a(:view_history_link, css: '#ca-history a')
+ a(:old_version_link, css: '#pagehistory a.mw-changeslist-date')
end
diff --git a/tests/parser/parserTest.inc b/tests/parser/parserTest.inc
index 1cffa20c..f429c30a 100644
--- a/tests/parser/parserTest.inc
+++ b/tests/parser/parserTest.inc
@@ -155,7 +155,7 @@ class ParserTest {
static function setUp() {
global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc,
- $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache,
+ $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory,
$wgExtraNamespaces, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo,
$wgExtraInterlanguageLinkPrefixes, $wgLocalInterwikis,
$parserMemc, $wgThumbnailScriptPath, $wgScriptPath,
@@ -211,7 +211,6 @@ class ParserTest {
$wgParserCacheType = CACHE_NONE;
}
- $wgEnableParserCache = false;
DeferredUpdates::clearPendingUpdates();
$wgMemc = wfGetMainCache(); // checks $wgMainCacheType
$messageMemc = wfGetMessageCacheStorage();
@@ -890,9 +889,9 @@ class ParserTest {
'wgDisableTitleConversion' => false,
// Tidy options.
'wgUseTidy' => isset( $opts['tidy'] ),
- 'wgAlwaysUseTidy' => false,
+ 'wgTidyConfig' => null,
'wgDebugTidy' => false,
- 'wgTidyConf' => $IP . '/includes/tidy.conf',
+ 'wgTidyConf' => $IP . '/includes/tidy/tidy.conf',
'wgTidyOpts' => '',
'wgTidyInternal' => $this->tidySupport->isInternal(),
);
@@ -937,6 +936,7 @@ class ParserTest {
$wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp';
MagicWord::clearCache();
+ MWTidy::destroySingleton();
return $context;
}
@@ -1219,6 +1219,7 @@ class ParserTest {
FileBackendGroup::destroySingleton();
LockManagerGroup::destroySingletons();
LinkCache::singleton()->clear();
+ MWTidy::destroySingleton();
foreach ( $this->savedGlobals as $var => $val ) {
$GLOBALS[$var] = $val;
diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt
index e9653529..c8c63f39 100644
--- a/tests/parser/parserTests.txt
+++ b/tests/parser/parserTests.txt
@@ -119,6 +119,13 @@ Template:echo_with_div
!! endarticle
!! article
+Template:blank_param
+!! text
+{{{1}}}
+{{{}}}
+!! endarticle
+
+!! article
Template:table_attribs
!! text
<noinclude>
@@ -154,6 +161,22 @@ Template:table_attribs_5
!! endarticle
!! article
+Template:table_attribs_6
+!! text
+style="background: <nowiki>
+
+
+red;</nowiki>" |
+!! endarticle
+
+!! article
+Template:table_attribs_7
+!! text
+<noinclude>
+|</noinclude>style{{=}}"background:&#35;f9f9f9;"|Foo<ref>foo</ref>
+!! endarticle
+
+!! article
Template:table_header_cells
!! text
{{table_attribs}}!!style='color:red;'|''Bar''||style='color:brown;'|''Foo'' and Baz
@@ -166,6 +189,13 @@ Template:table_cells
!! endarticle
!! article
+Template:PartialTable
+!! text
+{|
+|-
+!! endarticle
+
+!! article
Template:image_attribs
!! text
<noinclude>
@@ -808,15 +838,12 @@ parsoid=wt2html
!!end
# same html as previous, but wikitext adjusted to match parsoid html2wt
-# skipping wt2html and html2html because it wants to put <i> before <b>
!! test
Italics and bold: 5-quote opening sequence: (5,2+3)
-!! options
-parsoid=wt2wt,html2wt
!! wikitext
'''''foo'''''
-!! html
-<p><b><i>foo</i></b>
+!! html/*
+<p><i><b>foo</b></i>
</p>
!! end
@@ -1300,7 +1327,7 @@ Non-word characters don't terminate tag names + tidy
Non-word characters are valid in extension tags (T19663)
!! wikitext
<tåg>tåg</tåg>
-!! html
+!! html/php
<pre>
'tåg'
array (
@@ -1311,11 +1338,15 @@ array (
!! test
Isolated close tags should be treated as literal text (bug 52760)
+!! options
+parsoid=wt2html
!! wikitext
</b>
<s.foo>s</s>
-!! html+tidy
+!! html/php+tidy
+<p>&lt;s.foo&gt;s</p>
+!! html/parsoid
<p>&lt;s.foo&gt;s</p>
!! end
@@ -1349,9 +1380,11 @@ Bare pipe character from a template (bug 52363)
<nowiki> unordered list
!! wikitext
<nowiki>* This is not an unordered list item.</nowiki>
-!! html
+!! html/php
<p>* This is not an unordered list item.
</p>
+!! html/parsoid
+<p><span typeof="mw:Nowiki">* This is not an unordered list item.</span></p>
!! end
!! test
@@ -1364,7 +1397,7 @@ sed abit.
:and a colon
</nowiki>
-!! html
+!! html/php
<p>Lorem ipsum dolor
sed abit.
@@ -1373,6 +1406,14 @@ sed abit.
:and a colon
</p>
+!! html/parsoid
+<p><span typeof="mw:Nowiki">Lorem ipsum dolor
+
+sed abit.
+ sed nullum.
+
+:and a colon
+</span></p>
!! end
!! test
@@ -1386,7 +1427,7 @@ nowiki 3
*There is not nowiki.
*There is <nowiki>nowiki</nowiki>.
-!! html
+!! html/php
<dl><dd>There is not nowiki.</dd>
<dd>There is nowiki.</dd></dl>
<ol><li>There is not nowiki.</li>
@@ -1394,6 +1435,15 @@ nowiki 3
<ul><li>There is not nowiki.</li>
<li>There is nowiki.</li></ul>
+!! html/parsoid
+<dl><dd data-parsoid='{}'>There is not nowiki.</dd>
+<dd data-parsoid='{}'>There is <span typeof="mw:Nowiki">nowiki</span>.</dd></dl>
+
+<ol><li data-parsoid='{}'>There is not nowiki.</li>
+<li data-parsoid='{}'>There is <span typeof="mw:Nowiki">nowiki</span>.</li></ol>
+
+<ul><li data-parsoid='{}'>There is not nowiki.</li>
+<li data-parsoid='{}'>There is <span typeof="mw:Nowiki">nowiki</span>.</li></ul>
!! end
!! test
@@ -1407,11 +1457,11 @@ Entities inside <nowiki>
!! test
Entities inside template parameters
-!! options
-parsoid
!! wikitext
{{echo|&ndash;}}
-!! html
+!! html/php+tidy
+<p>–</p>
+!! html/parsoid
<p><span typeof="mw:Transclusion mw:Entity" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&amp;ndash;"}},"i":0}}]}'>&ndash;</span></p>
!! end
@@ -1419,17 +1469,27 @@ parsoid
Properly escape nowiki when combined with other wiki markup
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p>* &lt;/nowiki&gt; tag</p>
!! wikitext
-<nowiki>* &lt;/nowiki&gt;</nowiki> tag
+<nowiki>*</nowiki> <nowiki>&lt;/nowiki&gt;</nowiki> tag
+!! end
+
+!! test
+T93824: Put escaped HTML tags inside nowiki
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>&lt;h2&gt;foo&lt;/h2&gt;</p>
+!! wikitext
+<nowiki><h2>foo</h2></nowiki>
!! end
!! test
T71950: 1. Put nowiki as close to cause as possible, even with non-quote escapable chars
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p>This text: L'<a rel="mw:WikiLink" href="./Foo">Foo</a>
This text: L''<a rel="mw:WikiLink" href="./Foo">Foo</a>
This text: L'''<a rel="mw:WikiLink" href="./Foo">Foo</a>''</p>
@@ -1444,7 +1504,7 @@ This text: L<nowiki>'''</nowiki>[[Foo]]<nowiki>''</nowiki>
T71950: 2. Put nowiki as close to cause as possible, after ' :'
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p>This text : L''<a rel="mw:WikiLink" href="./Foo">Foo</a>
</p>
!! wikitext
@@ -1483,6 +1543,30 @@ parsoid=html2wt
{{echo|a <nowiki>}</nowiki>}}
!! end
+!! test
+Cases where "!!" needs nowiki protection
+!! options
+parsoid=html2wt
+!! html/parsoid
+<table>
+<tr><th>this needs protection !! here</th></tr>
+</table>
+
+<table>
+<tr><th>this does not need
+protection !! here</th></tr>
+</table>
+!! wikitext
+{|
+!<nowiki>this needs protection !! here</nowiki>
+|}
+
+{|
+!this does not need
+protection !! here
+|}
+!! end
+
###
### Comments
###
@@ -1587,8 +1671,10 @@ Comment whitespace
Comment semantics and delimiters
!! wikitext
<!-- --><!----><!-----><!------>
-!! html
+!! html/php
+!! html/parsoid
+<!-- --><!----><!--&#x2D;--><!--&#x2D;&#x2D;-->
!! end
!! test
@@ -1596,8 +1682,11 @@ Comment semantics and delimiters, redux
!! wikitext
<!-- In SGML every "foo" here would actually show up in the text -- foo -- bar
-- foo -- funky huh? ... -->
-!! html
+!! html/php
+!! html/parsoid
+<!-- In SGML every "foo" here would actually show up in the text &#x2D;&#x2D; foo &#x2D;&#x2D; bar
+&#x2D;&#x2D; foo &#x2D;&#x2D; funky huh? ... -->
!! end
!! test
@@ -1607,39 +1696,68 @@ Comment semantics and delimiters: directors cut
everything starting with < followed by !-- until the first -- and > we see,
that wouldn't be valid XML however, since in XML -- has to terminate a comment
-->-->
-!! html
+!! html/php
<p>--&gt;
</p>
+!! html/parsoid
+<!-- ... However we like to keep things simple and somewhat XML&#x2D;ish so we eat
+everything starting with < followed by !&#x2D;&#x2D; until the first &#x2D;&#x2D; and &#x3E; we see,
+that wouldn't be valid XML however, since in XML &#x2D;&#x2D; has to terminate a comment
+--><p>--></p>
!! end
!! test
Comment semantics: nesting
!! wikitext
<!--<!-- no, we're not going to do anything fancy here -->-->
-!! html
+!! html/php
<p>--&gt;
</p>
+!! html/parsoid
+<!--<!&#x2D;&#x2D; no, we're not going to do anything fancy here --><p>--></p>
!! end
+# Parsoid closes the unclosed comment, even if it means a slight
+# round-trip diff.
!! test
Comment semantics: unclosed comment at end
+!! options
+parsoid=wt2html,html2html
!! wikitext
<!--This comment will run out to the end of the document
-!! html
+!! html/php
+!! html/parsoid
+<!--This comment will run out to the end of the document-->
!! end
-# Bug 58184: document parsoid's behaviour
!! test
-Suppress comment closing tag in lenient browsers
-!! options
-parsoid=wt2html,html2html
+Comment semantics: normalize comments to play nice with XML and browsers
!! wikitext
-<!-- Browsers--!> think this is closed -->
+<!-- Browsers --!> think this is closed -->
+<!--> This would normally be text -->
+<!---> As would this -->
+<!-- XML doesn't like trailing dashes -------->
+<!-- Nor doubled hyphens -- anywhere in the data -->
+But this is not a comment.
!! html/php
+<p>But this is not a comment.
+</p>
+!! html/parsoid
+<!-- Browsers &#x2D;&#x2D;!&#x3E; think this is closed -->
+<!--&#x3E; This would normally be text -->
+<!--&#x2D;&#x3E; As would this -->
+<!-- XML doesn't like trailing dashes &#x2D;&#x2D;&#x2D;&#x2D;&#x2D;&#x2D;-->
+<!-- Nor doubled hyphens &#x2D;&#x2D; anywhere in the data -->
+<p>But this is not a comment.</p>
+!! end
+!! test
+Comment semantics: round-trip even text which contains encoded -->
+!! wikitext
+<!-- hello & goodbye - > --&gt; --&amp;gt; --&xx -->
!! html/parsoid
-<!-- Browsers--¡> think this is closed -->
+<!-- hello &#x26; goodbye &#x2D; &#x3E; &#x2D;&#x2D;&#x3E; &#x2D;&#x2D;&#x26;gt; &#x2D;&#x2D;&#x26;xx -->
!! end
!! test
@@ -1682,10 +1800,15 @@ parsoid=wt2html,wt2wt
!! wikitext
<!--c1-->*a
<!--c2--><!--c3--><!--c4-->*b
-!! html
-<ul>
+!! html/php
+<ul><li>a</li>
+<li>b</li></ul>
+
+!! html/parsoid
+<!--c1--><ul>
<li>a
</li>
+<!--c2--><!--c3--><!--c4-->
<li>b
</li>
</ul>
@@ -1894,7 +2017,7 @@ a [[Category:A1]] [[Category:A2]]
[[Category:A4]]
!! html/parsoid
<p>a</p>
-<link href="Category:A1"/> <link href="Category:A2"/> <link href="Category:A3"/> <link href="Category:A4"/>
+<link rel="mw:PageProp/Category" href="./Category:A1"/> <link rel="mw:PageProp/Category" href="./Category:A2"/> <link rel="mw:PageProp/Category" href="./Category:A3"/> <link rel="mw:PageProp/Category" href="./Category:A4"/>
!! end
!! test
@@ -1904,7 +2027,7 @@ parsoid=wt2html
!! wikitext
[[Category:A1]]a
!! html/parsoid
-<link href="Category:A1"/><p>a</p>
+<link rel="mw:PageProp/Category" href="./Category:A1"/><p>a</p>
!! end
###
@@ -1934,13 +2057,28 @@ Tabs don't trigger preformatted text
preformatted text.
This is preformatted text.
So is this.
-!! html
+!! html/php
<p> This is not
preformatted text.
</p>
<pre>This is preformatted text.
So is this.
</pre>
+!! html/parsoid
+<p> This is not
+ preformatted text.</p>
+<pre>This is preformatted text.
+ So is this.</pre>
+!! end
+
+!! test
+Space before tab needs nowiki pre protection
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p> a</p>
+!! wikitext
+<nowiki> </nowiki> a
!! end
!! test
@@ -2140,7 +2278,7 @@ Entities inside <pre>
</nowiki>
</pre>
-!! html
+!! html/php
<pre>
&lt;nowiki&gt;
</pre>
@@ -2153,6 +2291,18 @@ Entities inside <pre>
&lt;/pre&gt;
</p>
+!! html/parsoid
+<pre data-parsoid='{"stx":"html","strippedNL":true}'>&lt;nowiki>
+</pre>
+<p><span typeof="mw:Placeholder" data-parsoid='{"src":"&lt;/nowiki>"}'>&lt;/nowiki></span>
+&lt;/pre></p>
+
+<p><span typeof="mw:Nowiki">
+&lt;pre>
+&lt;nowiki>
+&lt;/pre>
+</span>
+&lt;/pre></p>
!! end
!! test
@@ -2209,13 +2359,17 @@ HTML pre followed by indent-pre
</pre>
!! end
+# Note that tidy removes the empty <p> tags from the start and end.
+# Parsoid does not, by design.
!!test
Block tag pre
-!!options
-parsoid
!! wikitext
<p><pre>foo</pre></p>
-!! html
+!! html/php+tidy
+<pre>
+foo
+</pre>
+!! html/parsoid
<p data-parsoid='{"stx":"html","autoInsertedEnd":true}'></p><pre data-parsoid='{"stx":"html"}'>foo</pre><p data-parsoid='{"autoInsertedStart":true,"stx":"html"}'></p>
!!end
@@ -2339,6 +2493,19 @@ Templates: Indent-Pre: 1f: Wrapping should be based on expanded content
!!end
!! test
+Pres with newline attributes
+!! wikitext
+<pre class="one
+two">hi</pre>
+!! html/php
+<pre class="one two">hi</pre>
+
+!! html/parsoid
+<pre class="one
+two" data-parsoid='{"stx":"html"}'>hi</pre>
+!! end
+
+!! test
Things that look like <pre> tags aren't treated as such
!! wikitext
Barack Obama <President> of the United States
@@ -2377,7 +2544,10 @@ Parsoid: handle pre with space after attribute
parsoid=wt2html
!! wikitext
<pre style="width:50%;" >{{echo|foo}}</pre>
-!! html
+!! html/php
+<pre style="width:50%;">{{echo|foo}}</pre>
+
+!! html/parsoid
<pre style="width:50%;">{{echo|foo}}</pre>
!! end
@@ -2583,32 +2753,32 @@ Templates: Other wikitext in parameter names (bug 67657)
#--------------------------------------------------------------------
!! test
Templates: Parsoid parameter escaping test 1
-!! options
-parsoid
!! wikitext
{{echo|[foo]|{{echo|[bar]}}}}
-!! html
+!! html/php+tidy
+<p>[foo]</p>
+!! html/parsoid
<p about="#mwt1" typeof="mw:Transclusion"
data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[foo]"},"2":{"wt":"{{echo|[bar]}}"}},"i":0}}]}'>[foo]</p>
!! end
!! test
Parsoid: Pipes in external links in template parameter
-!! options
-parsoid
!! wikitext
{{echo|[{{echo|http://example.com}} link]}}
-!! html
+!! html/php+tidy
+<p><a rel="nofollow" class="external text" href="http://example.com">link</a></p>
+!! html/parsoid
<p><a rel="mw:ExtLink" href="http://example.com" about="#mwt31" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[{{echo|http://example.com}} link]"}},"i":0}}]}'>link</a></p>
!! end
!! test
Parsoid: pipe in transclusion parameter
-!! options
-parsoid
!! wikitext
{{echo|http://foo.com/a&#124;b}}
-!! html
+!! html/php+tidy
+<p><a rel="nofollow" class="external free" href="http://foo.com/a%7Cb">http://foo.com/a%7Cb</a></p>
+!! html/parsoid
<p><a rel="mw:ExtLink" href="http://foo.com/a|b" about="#mwt1"
typeof="mw:Transclusion"
data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"http://foo.com/a&amp;#124;b"}},"i":0}}]}'>http://foo.com/a|b</a></p>
@@ -2620,7 +2790,9 @@ Parsoid: Pipe in external link target and content in template parameter
parsoid=html2wt,wt2wt
!! wikitext
{{echo|[http://foo.com/a&#124;b a&#124;b]}}
-!! html
+!! html/php+tidy
+<p><a rel="nofollow" class="external text" href="http://foo.com/a%7Cb">a|b</a></p>
+!! html/parsoid
<p><a rel="mw:ExtLink" href="http://foo.com/a|b" about="#mwt1"
typeof="mw:Transclusion"
data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},
@@ -2645,7 +2817,9 @@ parsoid=html2wt,wt2wt
{{echo|foo<nowiki>|</nowiki>bar}}
{{echo|<nowiki>&lt;div&gt;</nowiki>}}
{{echo|<nowiki></nowiki>}}
-!! html
+!! html/php+tidy
+<p>foo|bar &lt;div&gt;</p>
+!! html/parsoid
<p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo<nowiki>|</nowiki>bar"}},"i":0}}]}'}'>foo</span><span typeof="mw:Nowiki" about="#mwt1">|</span><span about="#mwt1">bar</span>
<span typeof="mw:Transclusion mw:Nowiki" about="#mwt2" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<nowiki>&amp;lt;div&amp;gt;</nowiki>"}},"i":0}}]}'><span typeof="mw:Entity">&lt;</span>div<span typeof="mw:Entity">&gt;</span></span>
<span typeof="mw:Transclusion mw:Nowiki" about="#mwt3" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<nowiki></nowiki>"}},"i":0}}]}'></span>
@@ -2659,19 +2833,21 @@ Templates: '=' char in nested transclusions should not trigger nowiki escapes or
parsoid=html2wt,wt2wt
!! wikitext
{{echo|{{echo|1=bar}}}}
-!! html
+!! html/php+tidy
+<p>bar</p>
+!! html/parsoid
<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{echo|1=bar}}"}},"i":0}}]}'>bar</p>
!! end
## Bug 56733
!! test
Templates parameters with special tokenizing behavior dont get modified because of arg escaping
-!! options
-parsoid
!! wikitext
{{echo|a : b}}
-!! html
-<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a : b"}},"i":0}}]}'>a<span typeof="mw:Placeholder" data-parsoid='{"isDisplayHack":true}'> </span>: b</p>
+!! html/php+tidy
+<p>a&#160;: b</p>
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a : b"}},"i":0}}]}'>a<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"isDisplayHack":true}'> </span>: b</p>
!! end
## Bug T73412
@@ -2679,13 +2855,23 @@ parsoid
Templates: Preserve blank parameter names
!! wikitext
{{echo|=foo}}
-!! html/php
-<p>{{{1}}}
-</p>
+!! html/php+tidy
+<p>{{{1}}}</p>
!! html/parsoid
<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"":{"wt":"foo"}},"i":0}}]}'>{{{1}}}</p>
!! end
+!! test
+Templates: Preserve blank parameter names in other positions
+!! wikitext
+{{blank_param|bar|=foo}}
+!! html/php+tidy
+<p>bar foo</p>
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]},{"k":"","named":true,"spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"blank_param","href":"./Template:Blank_param"},"params":{"1":{"wt":"bar"},"":{"wt":"foo"}},"i":0}}]}'>bar
+foo</p>
+!! end
+
###
### Parsoid-centric tests for testing RT edge cases for pre
###
@@ -3136,9 +3322,10 @@ parsoid=wt2html,wt2wt
!! wikitext
[[Category:foo]] <!-- No pre-wrapping -->
{{echo| [[Category:foo]]}} <!-- No pre-wrapping -->
-!! html
- <link rel="mw:PageProp/Category" href="./Category:Foo"> <!-- No pre-wrapping -->
-<span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" [[Category:foo]]"}},"i":0}}]}'> </span><link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1"> <!-- No pre-wrapping -->
+!! html/php+tidy
+!! html/parsoid
+ <link rel="mw:PageProp/Category" href="./Category:Foo"> <!-- No pre&#x2D;wrapping -->
+<span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" [[Category:foo]]"}},"i":0}}]}'> </span><link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1"> <!-- No pre&#x2D;wrapping -->
!! end
!! test
@@ -3149,9 +3336,22 @@ parsoid=wt2html,wt2wt
[[Category:foo]] a
[[Category:foo]] {{echo|b}}
!! html
-<pre>
-<link rel="mw:PageProp/Category" href="./Category:Foo"> a
-<link rel="mw:PageProp/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre>
+<pre><link rel="mw:PageProp/Category" href="./Category:Foo"> a
+ <link rel="mw:PageProp/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre>
+!! end
+
+!! test
+Indent-Pre: Newlines in comments shouldn't affect sol state
+!! wikitext
+a <!--
+foo
+--> b
+!! html/php+tidy
+<p>a b</p>
+!! html/parsoid
+<p>a <!--
+foo
+--> b</p>
!! end
###
@@ -3177,8 +3377,10 @@ foo
foo
</pre>
-!! html
-<pre>foo</pre>
+!! html/php+tidy
+<pre>
+foo
+</pre>
<pre>
foo
</pre>
@@ -3191,7 +3393,6 @@ foo
foo
</pre>
-
!! html/parsoid
<pre data-parsoid='{"stx":"html"}'>foo</pre>
@@ -3230,7 +3431,7 @@ haha
</pre>
-!! html
+!! html/php+tidy
<pre>
@@ -3247,7 +3448,6 @@ haha
</pre>
-
!! html/parsoid
<pre data-parsoid='{"stx":"html"}'>
@@ -3290,7 +3490,7 @@ HTML-pre: 3: other wikitext
'' no-italic ''
[[ NoLink ]]
</pre>
-!! html
+!! html/php
<pre>
* foo
# bar
@@ -3299,6 +3499,13 @@ HTML-pre: 3: other wikitext
[[ NoLink ]]
</pre>
+!! html/parsoid
+<pre data-parsoid='{"stx":"html","strippedNL":true}'>* foo
+# bar
+= no-h =
+'' no-italic ''
+[[ NoLink ]]
+</pre>
!!end
###
@@ -3570,20 +3777,26 @@ Definition Lists: Hacky use to indent tables, with comment before table
</tr></table></dd></dl></dd></dl>
!! end
-# Bug 52473
+# The trailing whitespace in this test is to catch a regression in
+# Parsoid after T54473.
!! test
Definition Lists: Hacky use to indent tables (WS-insensitive)
-!! options
-parsoid
!! wikitext
: {|
|a
|}
-!! html
-<dl>
-<dd> <table><tr><td>a</td></tr></table> </dd>
-</dl>
+!! html/php
+<dl><dd><table>
+<tr>
+<td>a
+</td></tr></table></dd></dl>
+
+!! html/parsoid
+<dl><dd> <table>
+<tbody><tr><td>a</td></tr>
+</tbody></table> </dd></dl>
!! end
+
## The PHP parser treats : items (dd) without a corresponding ; item (dt)
## as an empty dt item. It also ignores all but the last ";" when followed
## by ":" later on. So, ";" are not ignored in ";;;t3" but are ignored in
@@ -3616,7 +3829,7 @@ parsoid
##
## All Parsoid only definition list tests have this difference.
##
-## See also: https://bugzilla.wikimedia.org/show_bug.cgi?id=6569
+## See also: https://phabricator.wikimedia.org/T8569
## and http://lists.wikimedia.org/pipermail/wikitext-l/2011-November/000483.html
!! test
@@ -3706,12 +3919,19 @@ parsoid
!! test
Definition Lists: Nesting: Test 2 (Parsoid only)
-!! options
-parsoid
!! wikitext
;t1
::d2
-!! html
+!! html/php+tidy
+<dl>
+<dt>t1</dt>
+<dd>
+<dl>
+<dd>d2</dd>
+</dl>
+</dd>
+</dl>
+!! html/parsoid
<dl>
<dt>t1</dt>
<dd>
@@ -3726,12 +3946,27 @@ parsoid
!! test
Definition Lists: Nesting: Test 3 (Parsoid only)
-!! options
-parsoid
!! wikitext
:;t1
::::d2
-!! html
+!! html/php+tidy
+<dl>
+<dd>
+<dl>
+<dt>t1</dt>
+<dd>
+<dl>
+<dd>
+<dl>
+<dd>d2</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+!! html/parsoid
<dl>
<dd>
<dl>
@@ -4006,6 +4241,9 @@ Definition Lists: Mixed Lists: Test 11
# Another case where tidy converts a <dt> to a <dd> (but Parsoid doesn't).
+# From whitelist:
+# * The test is wrong, there are two colons where there should be :;
+# * The PHP parser is wrong to close the <dl> after the <dt> containing the <ul>.
!! test
Definition Lists: Weird Ones: Test 1
!! wikitext
@@ -4063,7 +4301,7 @@ Definition Lists: Weird Ones: Test 1
<dl>
<dt>
<dl>
-<dt> foo<span typeof="mw:Placeholder">&nbsp;</span></dt>
+<dt> foo<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span></dt>
<dd data-parsoid='{"stx":"row"}'> bar (who uses this?)</dd>
</dl></dt>
</dl></dd>
@@ -4120,6 +4358,17 @@ Definition Lists: colons occurring in tags
</dl>
</dd>
</dl>
+!! html/parsoid
+<dl><dt>a</dt><dd data-parsoid='{"stx":"row"}'>b</dd>
+<dt><b>a:b</b></dt>
+<dt><i data-parsoid='{"stx":"html"}'>a:b</i></dt>
+<dt><span data-parsoid='{"stx":"html"}'>a:b</span></dt>
+<dt><div data-parsoid='{"stx":"html"}'>a:b</div></dt>
+<dt><div data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a</div></dt>
+<dd>b</dd>
+<dt><span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a:b"}},"i":0}}]}'>a:b</span></dt>
+<dt><i about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&#39;&#39;a:b&#39;&#39;"}},"i":0}}]}'>a:b</i>
+<dl><dt><dl><dt><i>a:b</i></dt></dl></dt></dl></dt></dl>
!! end
!! test
@@ -4441,6 +4690,25 @@ http://example.com/url_with_entity&#60;
!! end
!! test
+External links: Lone protocols are never linked (T105697)
+!! wikitext
+http://
+http://;
+(http://)
+bitcoin:
+bitcoin:;
+(bitcoin:)
+!! html
+<p>http://
+http://;
+(http://)
+bitcoin:
+bitcoin:;
+(bitcoin:)
+</p>
+!! end
+
+!! test
External links: No preceding word characters allowed (bug 65278)
!! wikitext
NOPEhttp://example.com
@@ -4981,38 +5249,6 @@ External link containing a single quote. (bug 63947)
<p><a rel="mw:ExtLink" href="//foo.org/bar'baz">bang</a></p>
!! end
-
-!! test
-External link containing a period in the anchor. (bug 63947)
-!! wikitext
-[//foo.org/bar#baz. bang]
-
-[//foo.org/bar. bang]
-!! html/php
-<p><a rel="nofollow" class="external text" href="//foo.org/bar#baz.">bang</a>
-</p><p><a rel="nofollow" class="external text" href="//foo.org/bar.">bang</a>
-</p>
-!! html/parsoid
-<p><a rel="mw:ExtLink" href="//foo.org/bar#baz.">bang</a></p>
-<p><a rel="mw:ExtLink" href="//foo.org/bar.">bang</a></p>
-!! end
-
-!! test
-External link containing a single quote. (bug 63947)
-!! wikitext
-[//foo.org/bar'baz]
-
-[//foo.org/bar'baz bang]
-!! html/php
-<p><a rel="nofollow" class="external autonumber" href="//foo.org/bar'baz">[1]</a>
-</p><p><a rel="nofollow" class="external text" href="//foo.org/bar'baz">bang</a>
-</p>
-!! html/parsoid
-<p><a rel="mw:ExtLink" href="//foo.org/bar'baz"></a></p>
-<p><a rel="mw:ExtLink" href="//foo.org/bar'baz">bang</a></p>
-!! end
-
-
!! test
External link containing double-single-quotes in text '' (bug 4598 sanity check)
!! wikitext
@@ -5048,9 +5284,22 @@ External link containing double-single-quotes with no space separating the url f
External link with comments in link text
!! wikitext
[http://www.google.com Google <!-- comment -->]
-!! html
+!! html/php
<p><a rel="nofollow" class="external text" href="http://www.google.com">Google </a>
</p>
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://www.google.com">Google <!-- comment --></a></p>
+!! end
+
+!! test
+External link to bare IPv4 address
+!! wikitext
+[http://192.168.0.1 Link]
+!! html/php
+<p><a rel="nofollow" class="external text" href="http://192.168.0.1">Link</a>
+</p>
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://192.168.0.1">Link</a></p>
!! end
!! test
@@ -5088,14 +5337,129 @@ http://example.com/index.php?foozoid&#x5B;&#x5D;=bar
!! end
!! test
-IPv6 urls (bug 21261)
-!! options
-disabled
+IPv6 urls, autolink format (T23261)
!! wikitext
http://[2404:130:0:1000::187:2]/index.php
-!! html
+
+Examples from RFC 2373, section 2.2:
+* http://[1080::8:800:200C:417A]/unicast
+* http://[FF01::101]/multicast
+* http://[::1]/loopback
+* http://[::]/unspecified
+* http://[::13.1.68.3]/ipv4compat
+* http://[::FFFF:129.144.52.38]/ipv4compat
+
+Examples from RFC 2732, section 2:
+* http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
+* http://[1080:0:0:0:8:800:200C:417A]/index.html
+* http://[3ffe:2a00:100:7031::1]
+* http://[1080::8:800:200C:417A]/foo
+* http://[::192.9.5.5]/ipng
+* http://[::FFFF:129.144.52.38]:80/index.html
+* http://[2010:836B:4179::836B:4179]
+
+!! html/php
<p><a rel="nofollow" class="external free" href="http://[2404:130:0:1000::187:2]/index.php">http://[2404:130:0:1000::187:2]/index.php</a>
-</p>
+</p><p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc2373">RFC 2373</a>, section 2.2:
+</p>
+<ul><li> <a rel="nofollow" class="external free" href="http://[1080::8:800:200C:417A]/unicast">http://[1080::8:800:200C:417A]/unicast</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[FF01::101]/multicast">http://[FF01::101]/multicast</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[::1]/loopback">http://[::1]/loopback</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[::]/unspecified">http://[::]/unspecified</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[::13.1.68.3]/ipv4compat">http://[::13.1.68.3]/ipv4compat</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[::FFFF:129.144.52.38]/ipv4compat">http://[::FFFF:129.144.52.38]/ipv4compat</a></li></ul>
+<p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc2732">RFC 2732</a>, section 2:
+</p>
+<ul><li> <a rel="nofollow" class="external free" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a></li>
+<li> <a rel="nofollow" class="external free" href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a></li></ul>
+
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://[2404:130:0:1000::187:2]/index.php">http://[2404:130:0:1000::187:2]/index.php</a></p>
+
+<p>Examples from <a href="//tools.ietf.org/html/rfc2373" rel="mw:ExtLink">RFC 2373</a>, section 2.2:</p>
+<ul><li> <a rel="mw:ExtLink" href="http://[1080::8:800:200C:417A]/unicast">http://[1080::8:800:200C:417A]/unicast</a></li>
+<li> <a rel="mw:ExtLink" href="http://[FF01::101]/multicast">http://[FF01::101]/multicast</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::1]/loopback">http://[::1]/loopback</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::]/unspecified">http://[::]/unspecified</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::13.1.68.3]/ipv4compat">http://[::13.1.68.3]/ipv4compat</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::FFFF:129.144.52.38]/ipv4compat">http://[::FFFF:129.144.52.38]/ipv4compat</a></li></ul>
+
+<p>Examples from <a href="//tools.ietf.org/html/rfc2732" rel="mw:ExtLink">RFC 2732</a>, section 2:</p>
+<ul><li> <a rel="mw:ExtLink" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a></li>
+<li> <a rel="mw:ExtLink" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a></li>
+<li> <a rel="mw:ExtLink" href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a></li>
+<li> <a rel="mw:ExtLink" href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a></li>
+<li> <a rel="mw:ExtLink" href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a></li></ul>
+!! end
+
+!! test
+IPv6 urls, bracketed format (T23261)
+!! wikitext
+[http://[2404:130:0:1000::187:2]/index.php test]
+
+Examples from RFC 2373, section 2.2:
+* [http://[1080::8:800:200C:417A] unicast]
+* [http://[FF01::101] multicast]
+* [http://[::1]/ loopback]
+* [http://[::] unspecified]
+* [http://[::13.1.68.3] ipv4compat]
+* [http://[::FFFF:129.144.52.38] ipv4compat]
+
+Examples from RFC 2732, section 2:
+* [http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html 1]
+* [http://[1080:0:0:0:8:800:200C:417A]/index.html 2]
+* [http://[3ffe:2a00:100:7031::1] 3]
+* [http://[1080::8:800:200C:417A]/foo 4]
+* [http://[::192.9.5.5]/ipng 5]
+* [http://[::FFFF:129.144.52.38]:80/index.html 6]
+* [http://[2010:836B:4179::836B:4179] 7]
+
+!! html/php
+<p><a rel="nofollow" class="external text" href="http://[2404:130:0:1000::187:2]/index.php">test</a>
+</p><p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc2373">RFC 2373</a>, section 2.2:
+</p>
+<ul><li> <a rel="nofollow" class="external text" href="http://[1080::8:800:200C:417A]">unicast</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[FF01::101]">multicast</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[::1]/">loopback</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[::]">unspecified</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[::13.1.68.3]">ipv4compat</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[::FFFF:129.144.52.38]">ipv4compat</a></li></ul>
+<p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc2732">RFC 2732</a>, section 2:
+</p>
+<ul><li> <a rel="nofollow" class="external text" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">1</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">2</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[3ffe:2a00:100:7031::1]">3</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[1080::8:800:200C:417A]/foo">4</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[::192.9.5.5]/ipng">5</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[::FFFF:129.144.52.38]:80/index.html">6</a></li>
+<li> <a rel="nofollow" class="external text" href="http://[2010:836B:4179::836B:4179]">7</a></li></ul>
+
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://[2404:130:0:1000::187:2]/index.php">test</a></p>
+
+<p>Examples from <a href="//tools.ietf.org/html/rfc2373" rel="mw:ExtLink">RFC 2373</a>, section 2.2:</p>
+<ul><li> <a rel="mw:ExtLink" href="http://[1080::8:800:200C:417A]">unicast</a></li>
+<li> <a rel="mw:ExtLink" href="http://[FF01::101]">multicast</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::1]/">loopback</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::]">unspecified</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::13.1.68.3]">ipv4compat</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::FFFF:129.144.52.38]">ipv4compat</a></li></ul>
+
+<p>Examples from <a href="//tools.ietf.org/html/rfc2732" rel="mw:ExtLink">RFC 2732</a>, section 2:</p>
+<ul><li> <a rel="mw:ExtLink" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">1</a></li>
+<li> <a rel="mw:ExtLink" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">2</a></li>
+<li> <a rel="mw:ExtLink" href="http://[3ffe:2a00:100:7031::1]">3</a></li>
+<li> <a rel="mw:ExtLink" href="http://[1080::8:800:200C:417A]/foo">4</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::192.9.5.5]/ipng">5</a></li>
+<li> <a rel="mw:ExtLink" href="http://[::FFFF:129.144.52.38]:80/index.html">6</a></li>
+<li> <a rel="mw:ExtLink" href="http://[2010:836B:4179::836B:4179]">7</a></li></ul>
!! end
!! test
@@ -5113,7 +5477,8 @@ Non-extlinks in brackets
[{{echo|foo}}l's errand]
[url={{echo|foo}}]
[url=http://example.com]
-!! html
+[http:// bare protocols don't count]
+!! html/php
<p>[foo]
[foo bar]
[foo <i>bar</i>]
@@ -5126,7 +5491,22 @@ Non-extlinks in brackets
[fool's errand]
[url=foo]
[url=<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>]
+[http:// bare protocols don't count]
</p>
+!! html/parsoid
+<p>[foo]
+[foo bar]
+[foo <i>bar</i>]
+[fool's] errand
+[fool's errand]
+[<span typeof="mw:Placeholder" data-parsoid='{"src":"{{echo|foo}}"}'>foo</span>]
+[<span typeof="mw:Placeholder" data-parsoid='{"src":"{{echo|foo}}"}'>foo</span> bar]
+[<span typeof="mw:Placeholder" data-parsoid='{"src":"{{echo|foo}}"}'>foo</span> <i>bar</i>]
+[<span typeof="mw:Placeholder" data-parsoid='{"src":"{{echo|foo}}l&#39;s"}'>fool's</span>] errand
+[<span typeof="mw:Placeholder" data-parsoid='{"src":"{{echo|foo}}l&#39;s"}'>fool's</span> errand]
+[<span typeof="mw:Placeholder" data-parsoid='{"src":"url={{echo|foo}}"}'>url=foo</span>]
+[url=<a rel="mw:ExtLink" href="http://example.com">http://example.com</a>]
+[http:// bare protocols don't count]</p>
!! end
!! test
@@ -5208,15 +5588,55 @@ Parenthesis in external links, w/ transclusion or comment
!! end
!! test
-Replace invalid link targets when serializing
+Serialize <a> tags with invalid link targets as plain text
!! options
parsoid=html2wt
-!! html
-<a rel="mw:WikiLink" href="./]] foo [[bar">Manual</a>
+!! html/parsoid
+<a rel="mw:WikiLink" href="[[foo]]">text</a>
+<a rel="mw:WikiLink" href="[[foo]]">*text</a>
+<a rel="mw:WikiLink" href="[[foo]]">[[foo]]</a>
+<a rel="mw:WikiLink" href="[[foo]]">*a [[foo]]</a>
!! wikitext
-[[MediaWiki:Badtitletext|Manual]]
+text
+<nowiki>*</nowiki>text
+<nowiki>[[foo]]</nowiki>
+<nowiki>*a [[foo]]</nowiki>
!! end
+!! test
+mw:ExtLink -vs- mw:WikiLink (T94723)
+!! options
+parsoid=html2wt
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Foo" title="Foo" data-parsoid='{"stx":"piped","a":{"href":"./Foo"},"sa":{"href":"Foo"},"dsr":[0,11,6,2]}'>Bar</a>
+<a rel="mw:WikiLink" href="./Foo" title="Foo">Bar</a>
+<a rel="mw:WikiLink" href="http://en.wikipedia.org/wiki/Foo" title="Foo">Bar</a>
+<a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/Foo" title="Foo">Bar</a>
+<p>
+<a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/European_Robin">European Robin</a>
+<a rel="mw:WikiLink" href="http://en.wikipedia.org/wiki/European_Robin">European Robin</a>
+</p>
+!! wikitext
+[[Foo|Bar]]
+[[Foo|Bar]]
+[[wikipedia:Foo|Bar]]
+[[wikipedia:Foo|Bar]]
+
+[[wikipedia:European_Robin|European Robin]]
+[[wikipedia:European_Robin|European Robin]]
+!! end
+
+!! test
+mw:ExtLink linking to a interwiki URL can be round-tripped losslessly (T94723)
+!! options
+parsoid=wt2wt
+!! wikitext
+[http://en.wikipedia.org/wiki/European_Robin European Robin]
+!! html/parsoid
+THIS SECTION IS NOT USED (but Parsoid won't run the test without it)
+!! end
+
+
###
### Quotes
###
@@ -5280,7 +5700,9 @@ Plain ''italic'''s plain
</p><p><b>Bold tag left open</b>
</p><p><i>Italic tag left open</i>
</p><p>Normal text.
-</p><p><b>This year'</b>s election <i>should</i> beat <b>last year'</b>s.
+</p>
+<!-- Unmatching number of opening, closing tags: -->
+<p><b>This year'</b>s election <i>should</i> beat <b>last year'</b>s.
</p><p><i>Tom<b>s car is bigger than </b></i><b>Susan</b>s.
</p><p>Plain <i>italic'</i>s plain
</p>
@@ -5480,6 +5902,7 @@ Simple table but with multiple dashes for row wikitext
</td></tr></table>
!! end
+
!! test
Multiplication table
!! wikitext
@@ -5601,6 +6024,69 @@ Accept "||" in indented table headings
!! end
!! test
+Accept "!!" in templates
+!! wikitext
+{|
+!a {{echo|b!!c}}
+|}
+!! html/php
+<table>
+<tr>
+<th>a b</th>
+<th>c
+</th></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><th typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":["!a ",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b!!c"}},"i":0}}]}'>a b</th><th about="#mwt1">c</th></tr>
+!! end
+
+!! test
+Accept "!!" in table headings after newline
+!! wikitext
+{|
+!a
+b!!c
+|}
+!! html/php
+<table>
+<tr>
+<th>a
+<p>b!!c
+</p>
+</th></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><th>a
+<p>b!!c</p></th></tr>
+</tbody></table>
+!! end
+
+!! test
+Accept "!!" in table data of mixed wikitext / html syntax
+!! wikitext
+{|
+!a
+<tr><td>b!!c</td></tr>
+|}
+!! html+tidy
+<table>
+<tr>
+<th>a</th>
+</tr>
+<tr>
+<td>b!!c</td>
+</tr>
+</table>
+!! html/parsoid
+<table>
+<tbody><tr><th>a</th></tr>
+<tr data-parsoid='{"stx":"html"}'><td data-parsoid='{"stx":"html"}'>b!!c</td></tr>
+</tbody></table>
+!! end
+
+!! test
Accept empty attributes in td/th cells (td/th cells starting with leading ||)
!! wikitext
{|
@@ -5746,10 +6232,37 @@ Invalid attributes in table cell (bug 1830)
!! end
-# The "|}" to close the table is missing from the input, so parsoid's
-# *2wt modes will fail.
!! test
-Table security: embedded pipes (http://lists.wikimedia.org/mailman/htdig/wikitech-l/2006-April/022293.html)
+Table cell attributes: Pipes protected by nowikis should be treated as a plain character
+!! wikitext
+{|
+| title="foo" |bar
+| title="foo<nowiki>|</nowiki>" |bar
+| title="foo<nowiki>|</nowiki>" bar
+|}
+!! html/php
+<table>
+<tr>
+<td title="foo">bar
+</td>
+<td title="foo&#124;">bar
+</td>
+<td> title="foo|" bar
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><td title="foo">bar</td>
+<td title="foo|" data-parsoid='{"a":{"title":"foo|"},"sa":{"title":"foo&lt;nowiki>|&lt;/nowiki>"},"autoInsertedEnd":true}'>bar</td>
+<td> title="foo<span typeof="mw:Nowiki">|</span>" bar</td></tr>
+</tbody></table>
+!! end
+
+# See: http://lists.wikimedia.org/mailman/htdig/wikitech-l/2006-April/022293.html
+# N.B. The "|}" to close the table is missing from the input, so parsoid's
+# *2wt modes will fail.
+!! test
+Table security: embedded pipes
!! options
parsoid=wt2html,html2html
!! wikitext
@@ -5767,12 +6280,14 @@ parsoid=wt2html,html2html
!! html/parsoid
<table><tbody>
<tr>
-<td><a rel="mw:ExtLink" href="ftp://|x||"></a>" onmouseover="alert(document.cookie)">test</td></tr></tbody></table>
+<td data-parsoid='{"startTagSrc":"| ","attrSepSrc":"|","autoInsertedEnd":true}'><a rel="mw:ExtLink" href="ftp://|x||"></a>" onmouseover="alert(document.cookie)">test</td></tr></tbody></table>
!! end
-# FIXME: The php output is broken.
+# FIXME: The output seems broken. Filed as T110268.
!! test
! and || in td attributes should not be parsed as <th>/<td>
+!! options
+parsoid=wt2html
!! wikitext
{|
| style="color: red !important;" data-contrived="put this here ||" | foo
@@ -5786,7 +6301,7 @@ parsoid=wt2html,html2html
!! html/parsoid
<table>
-<tbody><tr><td style="color: red !important;" data-contrived="put this here ||" data-parsoid='{"autoInsertedEnd":true}'> foo</td></tr>
+<tbody><tr><td> style="color: red !important;" data-contrived="put this here </td><td data-parsoid='{"stx_v":"row","a":{"\"":null},"sa":{"\"":""},"autoInsertedEnd":true}'> foo</td></tr>
</tbody></table>
!! end
@@ -5893,6 +6408,50 @@ Indented table markup mixed with indented pre content (proposed in bug 6200)
!! end
!! test
+4. Template-generated table cell attributes and cell content inside a templated table
+!! wikitext
+{{tbl-start}}
+!align=center {{table_header_cells}}
+|-
+|align=center {{table_cells}}
+{{tbl-end}}
+!! html/php
+<table>
+<tr>
+<th align="center" style="color:red;">Foo</th>
+<th style="color:red;"><i>Bar</i></th>
+<th style="color:brown;"><i>Foo</i> and Baz
+</th></tr>
+<tr>
+<td align="center" style="color:red;">Foo</td>
+<td style="color:red;"><i>Bar</i></td>
+<td style="color:brown;"><i>Foo</i> and Baz
+</td></tr></table>
+
+!! html/parsoid
+<table about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[],[],[],[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"tbl-start","href":"./Template:Tbl-start"},"params":{},"i":0}},"\n!align=center ",{"template":{"target":{"wt":"table_header_cells","href":"./Template:Table_header_cells"},"params":{},"i":1}},"\n|-\n|align=center ",{"template":{"target":{"wt":"table_cells","href":"./Template:Table_cells"},"params":{},"i":2}},"\n",{"template":{"target":{"wt":"tbl-end","href":"./Template:Tbl-end"},"params":{},"i":3}}]}'>
+<tbody><tr><th align="center" style="color:red;">Foo</th><th style="color:red;"><i>Bar</i></th><th style="color:brown;"><i>Foo</i> and Baz</th></tr>
+<tr>
+<td align="center" style="color:red;">Foo</td><td style="color:red;"><i>Bar</i></td><td style="color:brown;"><i>Foo</i> and Baz</td></tr>
+</tbody></table>
+!! end
+
+## Edge case fix to prevent future regressions
+!! test
+T107652: <ref>s in templates that also generate table cell attributes should be rendered properly
+!! wikitext
+{|
+|{{table_attribs_7}}
+|}
+<references />
+!! html/parsoid
+<table>
+<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<span class="mw-ref" id="cite_ref-1" rel="dc:references" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></span></td></tr>
+</tbody></table>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+!! end
+
+!! test
Table with row followed by newlines and table heading
!! wikitext
{|
@@ -6305,7 +6864,7 @@ parsoid=wt2html,wt2wt
Parsoid: Default to a newline after tables in new content (bug 51219)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<table><tbody>
<tr><td>foo</td></tr></tbody></table> bar
<table><tbody>
@@ -6325,7 +6884,7 @@ parsoid=html2wt
Parsoid: newline inducing block nodes don't suppress <nowiki>
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
a<h1>foo</h1>
!! wikitext
<nowiki> </nowiki>a
@@ -6359,9 +6918,6 @@ parsoid=wt2html,wt2wt
</tbody></table>
!! end
-
-# PHP throws away the (semi-broken) "foo" class here; Parsoid
-# preserves it.
!!test
Parsoid: Recover better from broken table attributes
!!options
@@ -6372,7 +6928,7 @@ parsoid=wt2html
foo
|}
!!html/php+tidy
-<table>
+<table class="foo">
<tr>
<td class="bar">
<p>foo</p>
@@ -6388,10 +6944,27 @@ foo
!!end
!! test
+Tables: Digest broken attributes on table and tr tag
+!! options
+parsoid=wt2html
+!! wikitext
+{| || |} ++
+|- || || ++ --
+|- > [
+|}
+!! html
+<table>
+<tbody>
+<tr></tr>
+<tr></tr>
+</tbody></table>
+!! end
+
+!! test
Strip unsupported table tags
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<table>
<thead>
<tr>
@@ -6597,8 +7170,10 @@ Link with HTML entity in suffix / tail
Link with 3 brackets
!! wikitext
[[[Main Page]]]
+Foo [[[Main Page]]]
!! html
<p>[[[Main Page]]]
+Foo [[[Main Page]]]
</p>
!! end
@@ -6696,7 +7271,7 @@ Namespace takes precedence over interwiki link (bug 51680)
Link to namespace preferred over interwiki with correct rel attribute
!! options
parsoid=html2wt,html2html
-!! html
+!! html/parsoid
<p><a rel="mw:WikiLink" href="./MemoryAlpha:AlphaTest" title="MemoryAlpha:AlphaTest">MemoryAlpha:AlphaTest</a></p>
!! wikitext
[[MemoryAlpha:AlphaTest]]
@@ -6810,7 +7385,7 @@ Link containing a tilde
!! wikitext
[[Foo~bar]]
!! html/php
-<p><a href="/wiki/Foo%7Ebar" title="Foo~bar">Foo~bar</a>
+<p><a href="/wiki/Foo~bar" title="Foo~bar">Foo~bar</a>
</p>
!! html/parsoid
<p><a rel="mw:WikiLink" href="./Foo~bar" title="Foo~bar">Foo~bar</a></p>
@@ -6884,10 +7459,10 @@ Broken image links with HTML captions (bug 39700)
<a href="/index.php?title=Special:Upload&amp;wpDestFile=Nonexistent" class="new" title="File:Nonexistent">abc</a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&lt;script>&lt;/script>"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span>
-<span typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&lt;script>&lt;/script>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="100" width="100"/></a></span>
-<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&amp;lt;"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span>
-<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"a&lt;i>b&lt;/i>c"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span>
+<span typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="100" width="100"/></a></span>
+<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&lt;span typeof=\"mw:Entity\" data-parsoid=\"{&amp;quot;src&amp;quot;:&amp;quot;&amp;amp;lt;&amp;quot;,&amp;quot;srcContent&amp;quot;:&amp;quot;&lt;&amp;quot;,&amp;quot;dsr&amp;quot;:[107,111,null,null]}\">&amp;lt;&lt;/span>"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span>
+<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"a&lt;i data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;html&amp;quot;,&amp;quot;dsr&amp;quot;:[134,142,3,4]}\">b&lt;/i>c"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span></p>
!! end
!! test
@@ -7125,7 +7700,7 @@ title=[[User:test/123]]
<p><a href="#a">b</a>
</p>
!! html/parsoid
-<p><a rel="mw:WikiLink" href="../User:Test/123#a" data-parsoid='{"stx":"piped","a":{"href":"../User:Test/123#a"},"sa":{"href":"#a"}}'>b</a></p>
+<p><a rel="mw:WikiLink" href="./User:Test/123#a" data-parsoid='{"stx":"piped","a":{"href":"./User:Test/123#a"},"sa":{"href":"#a"}}'>b</a></p>
!! end
!! test
@@ -7204,7 +7779,7 @@ mótmælenda[[söfnuður|söfnuðir]]xxx
Parsoid link trail escaping
!! options
parsoid=html2wt,html2html
-!! html
+!! html/parsoid
<p><a rel="mw:WikiLink" href="Apple" title="Apple">apple</a>s</p>
!! wikitext
[[apple]]<nowiki/>s
@@ -7215,7 +7790,7 @@ Parsoid link prefix escaping
!! options
language=is
parsoid=html2wt,html2html
-!! html
+!! html/parsoid
<p>Aðrir mótmælenda<a rel="mw:WikiLink" href="Söfnuður" title="Söfnuður">söfnuður</a></p>
!! wikitext
Aðrir mótmælenda<nowiki/>[[söfnuður]]
@@ -7515,7 +8090,6 @@ Blah blah blah
[[ es :Spanish]]
[[ ZH :Chinese]]
[[es:Foo_bar]]
-[[es:Foo bar]]
!! html/php
<p>Blah blah blah
</p>
@@ -7524,7 +8098,21 @@ Blah blah blah
<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Spanish" />
<link rel="mw:PageProp/Language" href="http://zh.wikipedia.org/wiki/Chinese" />
<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo_bar" />
-<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo_bar" />
+!! end
+
+!! test
+Space and question mark encoding in interlanguage links (T95473)
+!! options
+parsoid=wt2html,wt2wt,html2html
+!! wikitext
+Blah blah blah
+[[es:Foo bar?]]
+!! html/php
+<p>Blah blah blah
+</p>
+!! html/parsoid
+<p>Blah blah blah</p>
+<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo_bar%3F" />
!! end
!! test
@@ -7587,7 +8175,7 @@ language=ln
Parsoid bug 53221: Wikilinks should be properly entity-escaped
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p>He&amp;nbsp;llo <a href="Foo" rel="mw:WikiLink">He&amp;nbsp;llo</a></p>
<p>He&amp;nbsp;llo <a href="He&amp;nbsp;llo" rel="mw:WikiLink">He&amp;nbsp;llo</a></p>
!! wikitext
@@ -7693,7 +8281,7 @@ Blah blah blah
</p>
!! html/parsoid
<p>Blah blah blah
-<a rel="mw:WikiLink" href="Template:Foo" title="Template:Foo">mi:Template:Foo</a></p>
+<a rel="mw:WikiLink" href="./Template:Foo" title="Template:Foo">mi:Template:Foo</a></p>
!! end
###
@@ -7702,12 +8290,10 @@ Blah blah blah
!! test
1. Simple redirect to page
-!! options
-parsoid
!! wikitext
#REDIRECT [[Main Page]]
-!! html
-<link rel="mw:PageProp/redirect" href="./Main_Page">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Main_Page"/>
!! end
!! test
@@ -7718,12 +8304,22 @@ parsoid
<link rel="mw:PageProp/redirect" href="./Main_Page" data-parsoid='{"src":"#REDIRECT ","a":{"href":"./Main_Page"},"sa":{"href":"Main_Page"}}'/>
!! end
+# Not a valid redirect in PHP (although perhaps it was, once upon a time)
+# This tests the Parsoid bail-out code.
!! test
3. Other redirect variants
!! wikitext
#REDIRECT [[<nowiki>[[Bar]]</nowiki>]]
!! html/parsoid
-<link rel="mw:PageProp/redirect" href="./%5B%5BBar%5D%5D" data-parsoid='{"src":"#REDIRECT ","a":{"href":"./%5B%5BBar%5D%5D"},"sa":{"href":"&lt;nowiki>[[Bar]]&lt;/nowiki>"}}'/>
+<ol><li data-parsoid>REDIRECT [[[[Bar]]]]</li></ol>
+!! end
+
+!! test
+4. Redirect to a templated destination
+!! wikitext
+#REDIRECT [[{{echo|Foo}}bar]]
+!! html/parsoid
+<link typeof="mw:ExpandedAttrs" rel="mw:PageProp/redirect" href="./Foobar" data-mw='{"attribs":[[{"txt":"href"},{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[12,24,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;Foo&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">Foo&lt;/span>bar"}]]}'/>
!! end
!! test
@@ -7732,7 +8328,7 @@ Empty redirect
parsoid=wt2html,wt2wt
!! wikitext
#REDIRECT [[]]
-!! html
+!! html/parsoid
<ol>
<li>REDIRECT [[]]</li></ol>
!! end
@@ -7745,8 +8341,8 @@ Optional colon in #REDIRECT
parsoid=wt2html,html2html
!! wikitext
#REDIRECT:[[Main Page]]
-!! html
-<link rel="mw:PageProp/redirect" href="./Main_Page">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Main_Page"/>
!! end
!! test
@@ -7761,8 +8357,8 @@ parsoid=wt2html,html2html
#REDIRECT
:
[[Main Page]]
-!! html
-<link rel="mw:PageProp/redirect" href="./Main_Page">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Main_Page"/>
!! end
!! test
@@ -7773,89 +8369,90 @@ Piped link in #REDIRECT
parsoid=wt2html
!! wikitext
#REDIRECT [[Main Page|bar]]
-!! html
-<link rel="mw:PageProp/redirect" href="./Main_Page">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Main_Page"/>
!! end
!! test
-Redirect to category
+Redirect to category (T104502)
!! options
-parsoid=wt2wt,wt2html
+parsoid=wt2html,wt2wt
!! wikitext
#REDIRECT [[Category:Foo]]
-!! html
-<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:PageProp/Category" href="./Category:Foo">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Category:Foo"/>
!! end
!! test
-Redirect to category with URL encoding
+Redirect to category with URL encoding (T104502)
!! options
parsoid=wt2html
!! wikitext
#REDIRECT [[Category%3AFoo]]
-!! html
-<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:PageProp/Category" href="./Category:Foo">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Category:Foo"/>
!! end
!! test
Redirect to category page
-!! options
-parsoid
!! wikitext
#REDIRECT [[:Category:Foo]]
-!! html
-<link rel="mw:PageProp/redirect" href="Category:Foo" title="Category:Foo"/>
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Category:Foo"/>
!! end
!! test
Redirect to image page (1)
-!! options
-parsoid
!! wikitext
#REDIRECT [[File:Wiki.png]]
-!! html
-<link rel="mw:PageProp/redirect" href="./File:Wiki.png">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./File:Wiki.png"/>
!! end
!! test
Redirect to image page (2)
-!! options
-parsoid
!! wikitext
#REDIRECT [[Image:Wiki.png]]
-!! html
-<link rel="mw:PageProp/redirect" href="./File:Wiki.png">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./File:Wiki.png" data-parsoid='{"src":"#REDIRECT ","a":{"href":"./File:Wiki.png"},"sa":{"href":"Image:Wiki.png"}}'/>
!! end
+# html2wt disabled because wts serializes as "#REDIRECT [[:en:File:Wiki.png]]"
+# Next test confirms this.
!! test
-Redirect to language
+Redirect to language (1) (T104918)
!! options
-parsoid
+parsoid=wt2html,wt2wt,html2html
!! wikitext
#REDIRECT [[en:File:Wiki.png]]
-!! html
-<link rel="mw:PageProp/redirect" href="./File:Wiki.png">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="//en.wikipedia.org/wiki/File:Wiki.png"/>
!! end
!! test
-Redirect to interwiki
-!! options
-parsoid
+Redirect to language (2) (T104918)
+!! wikitext
+#REDIRECT [[:en:File:Wiki.png]]
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="//en.wikipedia.org/wiki/File:Wiki.png"/>
+!! end
+
+!! test
+Redirect to interwiki (T104918)
!! wikitext
#REDIRECT [[meatball:File:Wiki.png]]
-!! html
-<link rel="mw:PageProp/redirect" href="./File:Wiki.png">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="http://www.usemod.com/cgi-bin/mb.pl?File:Wiki.png"/>
!! end
!! test
Non-English #REDIRECT
!! options
-parsoid
language=is
!! wikitext
#TILVÍSUN [[Main Page]]
-!! html
-<link rel="mw:PageProp/redirect" href="./Main_Page">
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Main_Page" data-parsoid='{"src":"#TILVÍSUN ","a":{"href":"./Main_Page"},"sa":{"href":"Main Page"}}'/>
!! end
!! test
@@ -7874,8 +8471,8 @@ some text
New redirect
!! options
parsoid=html2wt
-!! html
-<p>Foo<link rel="mw:PageProp/redirect" href="./Foo"></p>
+!! html/parsoid
+<p>Foo<link rel="mw:PageProp/redirect" href="./Foo"/></p>
!! wikitext
Foo
#REDIRECT [[Foo]]
@@ -7980,8 +8577,8 @@ Handling html with a br self-closing tag
<br title=bar/>
<br title=bar/ >
!! html/php
-<p><br title="title" />
-<br title="title" />
+<p><br title="" />
+<br title="" />
<br />
<br title="bar" />
<br title="bar" />
@@ -8225,7 +8822,7 @@ parsoid
!! wikitext
*<references />
!! html/parsoid
-<ul><li data-parsoid='{}'><ol class="references" typeof="mw:Extension/references" about="#mwt2" data-parsoid='{}' data-mw='{"name":"references","attrs":{}}'></ol></li></ul>
+<ul><li data-parsoid='{}'><ol class="mw-references" typeof="mw:Extension/references" about="#mwt2" data-parsoid='{}' data-mw='{"name":"references","attrs":{}}'></ol></li></ul>
!! end
!! test
@@ -8258,11 +8855,15 @@ List items are not parsed correctly following a <pre> block (bug 785)
* <pre>foo</pre>
* <pre>bar</pre>
* zar
-!! html
+!! html/php
<ul><li> <pre>foo</pre></li>
<li> <pre>bar</pre></li>
<li> zar</li></ul>
+!! html/parsoid
+<ul><li> <pre data-parsoid='{"stx":"html"}'>foo</pre></li>
+<li> <pre data-parsoid='{"stx":"html"}'>bar</pre></li>
+<li> zar</li></ul>
!! end
!! test
@@ -9306,7 +9907,7 @@ hi+world%3F%21
Magic Word: prioritize type info over data-parsoid
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<meta property="mw:PageProp/forcetoc" data-parsoid='{"magicSrc":"__NOTOC__"}'/>
!! wikitext
__FORCETOC__
@@ -9320,7 +9921,7 @@ parsoid=wt2wt,html2wt
foo
__NOTOC__
bar
-!! html
+!! html/parsoid
foo<meta property="mw:PageProp/notoc"/>bar
!! end
@@ -9331,10 +9932,19 @@ parsoid=wt2wt
language=de
!! wikitext
__NOEDITSECTION__
-!! html
+!! html/parsoid
<meta property="mw:PageProp/noeditsection" data-parsoid='{"magicSrc":"__NOEDITSECTION__"}'/>
!! end
+!!test
+__proto__ is treated as normal wikitext (T105997)
+!!wikitext
+__proto__
+!!html
+<p>__proto__
+</p>
+!!end
+
###
### Magic links
###
@@ -9342,27 +9952,33 @@ __NOEDITSECTION__
Magic links: internal link to RFC (bug 479)
!! wikitext
[[RFC 123]]
-!! html
+!! html/php
<p><a href="/index.php?title=RFC_123&amp;action=edit&amp;redlink=1" class="new" title="RFC 123 (page does not exist)">RFC 123</a>
</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./RFC_123" title="RFC 123">RFC 123</a></p>
!! end
!! test
Magic links: RFC (bug 479)
!! wikitext
RFC 822
-!! html
+!! html/php
<p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc822">RFC 822</a>
</p>
+!! html/parsoid
+<p><a href="//tools.ietf.org/html/rfc822" rel="mw:ExtLink">RFC 822</a></p>
!! end
!! test
Magic links: RFC (bug 65278)
!! wikitext
This is RFC 822 but thisRFC 822 is not RFC 822linked.
-!! html
+!! html/php
<p>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc822">RFC 822</a> but thisRFC 822 is not RFC 822linked.
</p>
+!! html/parsoid
+<p>This is <a href="//tools.ietf.org/html/rfc822" rel="mw:ExtLink">RFC 822</a> but thisRFC 822 is not RFC 822linked.</p>
!! end
!! test
@@ -9371,20 +9987,26 @@ Magic links: RFC (w/ non-newline whitespace, bug 28950/29025)
RFC &nbsp;&#160;&#0160;&#xA0;&#Xa0; 822
RFC
822
-!! html
+!! html/php
<p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc822">RFC 822</a>
RFC
822
</p>
+!! html/parsoid
+<p><a href="//tools.ietf.org/html/rfc822" rel="mw:ExtLink">RFC <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 822</a>
+RFC
+822</p>
!! end
!! test
Magic links: ISBN (bug 1937)
!! wikitext
ISBN 0-306-40615-2
-!! html
+!! html/php
<p><a href="/wiki/Special:BookSources/0306406152" class="internal mw-magiclink-isbn">ISBN 0-306-40615-2</a>
</p>
+!! html/parsoid
+<p><a href="./Special:BookSources/0306406152" rel="mw:WikiLink">ISBN 0-306-40615-2</a></p>
!! end
!! test
@@ -9395,7 +10017,7 @@ This is ISBN 978-0-316-09811-3 but thisISBN 978-0-316-09811-3 is not ISBN 978-0-
<p>This is <a href="/wiki/Special:BookSources/9780316098113" class="internal mw-magiclink-isbn">ISBN 978-0-316-09811-3</a> but thisISBN 978-0-316-09811-3 is not ISBN 978-0-316-09811-3linked.
</p>
!! html/parsoid
-<p>This is <a href="./Special:BookSources/9780316098113" rel="mw:ExtLink">ISBN 978-0-316-09811-3</a> but thisISBN 978-0-316-09811-3 is not ISBN 978-0-316-09811-3linked.</p>
+<p>This is <a href="./Special:BookSources/9780316098113" rel="mw:WikiLink">ISBN 978-0-316-09811-3</a> but thisISBN 978-0-316-09811-3 is not ISBN 978-0-316-09811-3linked.</p>
!! end
!! test
@@ -9406,31 +10028,41 @@ ISBN
9780316098113
ISBN 978
0316098113
-!! html
+!! html/php
<p><a href="/wiki/Special:BookSources/9780316098113" class="internal mw-magiclink-isbn">ISBN 978 0 316 09811 3</a>
ISBN
9780316098113
ISBN 978
0316098113
</p>
+!! html/parsoid
+<p><a href="./Special:BookSources/9780316098113" rel="mw:WikiLink">ISBN <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 978<span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span>0<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span>316<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span>09811<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span>3</a>
+ISBN
+9780316098113
+ISBN 978
+0316098113</p>
!! end
!! test
Magic links: PMID incorrectly converts space to underscore
!! wikitext
PMID 1234
-!! html
+!! html/php
<p><a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a>
</p>
+!! html/parsoid
+<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink">PMID 1234</a></p>
!! end
!! test
Magic links: PMID (bug 65278)
!! wikitext
This is PMID 1234 but thisPMID 1234 is not PMID 1234linked.
-!! html
+!! html/php
<p>This is <a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.
</p>
+!! html/parsoid
+<p>This is <a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.</p>
!! end
!! test
@@ -9439,11 +10071,15 @@ Magic links: PMID (w/ non-newline whitespace, bug 28950/29025)
PMID &nbsp;&#160;&#0160;&#xA0;&#Xa0; 1234
PMID
1234
-!! html
+!! html/php
<p><a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a>
PMID
1234
</p>
+!! html/parsoid
+<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink">PMID <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 1234</a>
+PMID
+1234</p>
!! end
###
@@ -9642,9 +10278,11 @@ Template with default value (value set)
Template redirect
!! wikitext
{{templateredirect}}
-!! html
+!! html/php
<p>(test)
</p>
+!! html/parsoid
+<link rel="mw:PageProp/redirect" href="./Template:Templatesimple" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"templateredirect","href":"./Template:Templateredirect"},"params":{},"i":0}}]}'/>
!! end
!! test
@@ -9883,6 +10521,24 @@ Template with targets containing wikilinks
!! end
!! article
+Template:''
+!! text
+bar
+!! endarticle
+
+!! test
+Templates: Double quotes as template target
+!! wikitext
+foo {{''}} baz
+!! html/php
+<p>foo bar baz
+</p>
+!! html/parsoid
+<p>foo <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"&#39;&#39;"},"params":{},"i":0}}]}'>bar</span> baz
+</p>
+!! end
+
+!! article
Template:MSGNW test
!! text
''None'' of '''this''' should be
@@ -9892,6 +10548,7 @@ Template:MSGNW test
<gallery>
File:Foobar.jpg
</gallery>
+<!-- comment -->
!! endarticle
# hmm, fix this or just deprecate msgnw and document its behavior?
@@ -9899,7 +10556,7 @@ File:Foobar.jpg
msgnw keyword
!! wikitext
{{msgnw:MSGNW test}}
-!! html
+!! html/php
<p>&#39;&#39;None&#39;&#39; of &#39;&#39;&#39;this&#39;&#39;&#39; should be
&#42; interpreted
&#32;but rather passed unmodified
@@ -9907,6 +10564,7 @@ msgnw keyword
&#60;gallery&#62;
File:Foobar.jpg
&#60;/gallery&#62;
+&#60;!-- comment --&#62;
</p>
!! end
@@ -9919,6 +10577,15 @@ int keyword
</p>
!! end
+!! test
+int keyword - non-existing message
+!! wikitext
+{{int:var}}
+!! html
+<p>&lt;var&gt;
+</p>
+!! end
+
!! article
Template:Includes
!! text
@@ -10160,7 +10827,7 @@ b}}
!! end
!! test
-Parsoid: Merge double tds (bug 50603)
+Parsoid: Merge double tds (T52603)
!! options
parsoid
!! wikitext
@@ -10174,7 +10841,7 @@ parsoid
!! end
!! test
-Parsoid: Merge double tds in nested transclusion content (bug 50603)
+Parsoid: Merge double tds in nested transclusion content (T52603)
!! options
parsoid
!! wikitext
@@ -10669,6 +11336,43 @@ Templates: Support for templates generating attributes and content
</tbody></table>
!! end
+!! test
+3. Entities and nowikis inside templated attributes should be handled correctly inside templated tables
+!! wikitext
+{{tbl-start}}
+|{{table_attribs_3}}
+{{tbl-end}}
+!! html/php
+<table>
+<tr>
+<td style="background:#f9f9f9;">Foo
+</td></tr></table>
+
+!! html/parsoid
+<table about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[],[],[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"tbl-start","href":"./Template:Tbl-start"},"params":{},"i":0}},"\n|",{"template":{"target":{"wt":"table_attribs_3","href":"./Template:Table_attribs_3"},"params":{},"i":1}},"\n",{"template":{"target":{"wt":"tbl-end","href":"./Template:Tbl-end"},"params":{},"i":2}}]}'>
+<tbody><tr><td style="background:#f9f9f9;">Foo</td></tr>
+</tbody></table>
+!! end
+
+# T107622
+!! test
+4. Entities and nowikis inside templated attributes should be handled correctly inside templated tables
+!! wikitext
+{|
+| {{table_attribs_6}} hi
+|}
+!! html/php
+<table>
+<tr>
+<td style="background: red;"> hi
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><td style="background: red;" typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["| ",{"template":{"target":{"wt":"table_attribs_6","href":"./Template:Table_attribs_6"},"params":{},"i":0}}," hi"]}'> hi</td></tr>
+</tbody></table>
+!! end
+
!!test
Templates: HTML Tables: 1. Generating start of a HTML table
!! wikitext
@@ -10896,6 +11600,46 @@ Templates: Wiki Tables: 6. Templated tags, templated td-tags
!!end
+## This test case is very specific to Parsoid's internals
+## and is hence only tested for Parsoid's code. Parsoid uses
+## a <meta> marker tag for <ref> tags and they are expanded
+## much later. We are verifying that this <meta> tag usage
+## doesn't prevent foster parenting.
+!!test
+Templates: Wiki Tables: 7. Fosterable <ref>s should get fostered
+!!wikitext
+{{PartialTable}}<ref>foo</ref>
+|}
+
+<references />
+!!html/parsoid
+<span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span><table about="#mwt2">
+<tbody>
+</tbody></table>
+
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+!!end
+
+!! test
+Templates: Wiki Tables: 8. Fosterable meta-tags should get fostered
+!! wikitext
+{{echo|
+{{{!}}
+{{!}}-}}
+<onlyinclude>
+|foo
+</onlyinclude>
+{{!}}}
+!! html/parsoid
+<span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"\n{{{!}}\n{{!}}-"}},"i":0}},"\n&lt;onlyinclude>\n|foo\n&lt;/onlyinclude>\n{{!}}}"]}'>
+</span><meta typeof="mw:Includes/OnlyInclude" about="#mwt1"/><table about="#mwt1">
+<tbody><tr>
+
+<td>foo
+<meta typeof="mw:Includes/OnlyInclude/End"/></td></tr>
+</tbody></table>
+!! end
+
!!test
Templates: Lists: Multi-line list-items via templates
!! wikitext
@@ -11093,41 +11837,40 @@ Parser Functions: 2. Nested use (only outermost should be marked up)
!! test
pre-save transform: subst:
!! options
-PST
+pst
!! wikitext
{{subst:test}}
-!! html
+!! html/php
This is a test template
!! end
!! test
pre-save transform: normal template
!! options
-PST
+pst
!! wikitext
{{test}}
-!! html
+!! html/php
{{test}}
!! end
!! test
pre-save transform: nonexistent template
!! options
-PST
+pst
!! wikitext
{{thistemplatedoesnotexist}}
-!! html
+!! html/php
{{thistemplatedoesnotexist}}
!! end
-
!! test
pre-save transform: subst magic variables
!! options
-PST
+pst
!! wikitext
{{subst:SITENAME}}
-!! html
+!! html/php
MediaWiki
!! end
@@ -11138,7 +11881,7 @@ pre-save transform: subst: templates with parameters
pst
!! wikitext
{{subst:paramtest|param="something else"}}
-!! html
+!! html/php
This is a test template with parameter "something else"
!! end
@@ -11154,11 +11897,10 @@ pre-save transform: nowiki in subst (bug 1188)
pst
!! wikitext
{{subst:nowikitest}}
-!! html
+!! html/php
<nowiki>'''not wiki'''</nowiki>
!! end
-
!! article
Template:commenttest
!! text
@@ -11171,7 +11913,7 @@ pre-save transform: comment in subst (bug 1936)
pst
!! wikitext
{{subst:commenttest}}
-!! html
+!! html/php
This template has <!-- a comment --> in it.
!! end
@@ -11181,7 +11923,7 @@ pre-save transform: unclosed tag
pst noxml
!! wikitext
<nowiki>'''not wiki'''
-!! html
+!! html/php
<nowiki>'''not wiki'''
!! end
@@ -11191,7 +11933,7 @@ pre-save transform: mixed tag case
pst noxml
!! wikitext
<NOwiki>'''not wiki'''</noWIKI>
-!! html
+!! html/php
<NOwiki>'''not wiki'''</noWIKI>
!! end
@@ -11201,7 +11943,7 @@ pre-save transform: unclosed comment in <nowiki>
pst noxml
!! wikitext
wiki<nowiki>nowiki<!--nowiki</nowiki>wiki
-!! html
+!! html/php
wiki<nowiki>nowiki<!--nowiki</nowiki>wiki
!!end
@@ -11229,7 +11971,7 @@ pre-save transform: comment containing gallery (bug 5024)
pst
!! wikitext
<!-- <gallery>data</gallery> -->
-!! html
+!! html/php
<!-- <gallery>data</gallery> -->
!!end
@@ -11239,7 +11981,7 @@ pre-save transform: comment containing extension
pst
!! wikitext
<!-- <tag>data</tag> -->
-!! html
+!! html/php
<!-- <tag>data</tag> -->
!!end
@@ -11249,7 +11991,7 @@ pre-save transform: comment containing nowiki
pst
!! wikitext
<!-- <nowiki>data</nowiki> -->
-!! html
+!! html/php
<!-- <nowiki>data</nowiki> -->
!!end
@@ -11259,7 +12001,7 @@ pre-save transform: <noinclude> in subst (bug 3298)
pst
!! wikitext
{{subst:Includes}}
-!! html
+!! html/php
Foobar
!! end
@@ -11269,7 +12011,7 @@ pre-save transform: <onlyinclude> in subst (bug 3298)
pst
!! wikitext
{{subst:Includes2}}
-!! html
+!! html/php
Foo
!! end
@@ -11291,7 +12033,7 @@ bug 22297: safesubst: works during PST
pst
!! wikitext
{{subst:SafeSubstTest}}{{safesubst:SubstTest}}
-!! html
+!! html/php
FoobarFoobar
!! end
@@ -11327,7 +12069,7 @@ pst
[[|Article (context)]]
[[Bar:X (Y) Z|]]
[[:Bar:X (Y) Z|]]
-!! html
+!! html/php
[[Article (context)|Article]]
[[Bar:Article|Article]]
[[:Bar:Article|Article]]
@@ -11348,7 +12090,7 @@ pst
[[:interwiki:Article|]]
[[interwiki:Bar:Article|]]
[[:interwiki:Bar:Article|]]
-!! html
+!! html/php
[[interwiki:Article|Article]]
[[:interwiki:Article|Article]]
[[interwiki:Bar:Article|Bar:Article]]
@@ -11361,7 +12103,7 @@ pre-save transform: context links ("pipe trick") with parens in title
pst title=[[Somearticle (context)]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Article (context)|Article]]
!! end
@@ -11373,7 +12115,7 @@ pst title=[[Someplace, Somewhere]]
[[|Otherplace]]
[[Otherplace, Elsewhere|]]
[[Otherplace, Elsewhere, Anywhere|]]
-!! html
+!! html/php
[[Otherplace, Somewhere|Otherplace]]
[[Otherplace, Elsewhere|Otherplace]]
[[Otherplace, Elsewhere, Anywhere|Otherplace]]
@@ -11386,7 +12128,7 @@ pst title=[[Someplace (IGNORED), Somewhere]]
!! wikitext
[[|Otherplace]]
[[Otherplace (place), Elsewhere|]]
-!! html
+!! html/php
[[Otherplace, Somewhere|Otherplace]]
[[Otherplace (place), Elsewhere|Otherplace]]
!! end
@@ -11398,7 +12140,7 @@ pst title=[[Who, me? (context)]]
!! wikitext
[[|Yes, you.]]
[[Me, Myself, and I (1937 song)|]]
-!! html
+!! html/php
[[Yes, you. (context)|Yes, you.]]
[[Me, Myself, and I (1937 song)|Me, Myself, and I]]
!! end
@@ -11409,7 +12151,7 @@ pre-save transform: context links ("pipe trick") with namespace
pst title=[[Ns:Somearticle]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article|Article]]
!! end
@@ -11419,7 +12161,7 @@ pre-save transform: context links ("pipe trick") with namespace and parens
pst title=[[Ns:Somearticle (context)]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article (context)|Article]]
!! end
@@ -11429,7 +12171,7 @@ pre-save transform: context links ("pipe trick") with namespace and comma
pst title=[[Ns:Somearticle, Context, Whatever]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article, Context, Whatever|Article]]
!! end
@@ -11439,7 +12181,7 @@ pre-save transform: context links ("pipe trick") with namespace, comma and paren
pst title=[[Ns:Somearticle, Context (context)]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article (context)|Article]]
!! end
@@ -11449,7 +12191,7 @@ pre-save transform: context links ("pipe trick") with namespace, parens and comm
pst title=[[Ns:Somearticle (IGNORED), Context]]
!! wikitext
[[|Article]]
-!! html
+!! html/php
[[Ns:Article, Context|Article]]
!! end
@@ -11464,7 +12206,7 @@ pst
[[|Article(context)]]
[[Bar:X(Y)Z|]]
[[:Bar:X(Y)Z|]]
-!! html
+!! html/php
[[Article(context)|Article]]
[[Bar:Article(context)|Article]]
[[:Bar:Article(context)|Article]]
@@ -11484,7 +12226,7 @@ pst
[[|Article (context)]]
[[Bar:X (Y) Z|]]
[[:Bar:X (Y) Z|]]
-!! html
+!! html/php
[[Article (context)|Article]]
[[Bar:Article (context)|Article]]
[[:Bar:Article (context)|Article]]
@@ -11504,7 +12246,7 @@ pst
[[|Article(context)]]
[[Bar:X(Y)Z|]]
[[:Bar:X(Y)Z|]]
-!! html
+!! html/php
[[Article(context)|Article]]
[[Bar:Article(context)|Article]]
[[:Bar:Article(context)|Article]]
@@ -11524,7 +12266,7 @@ pst
[[Bar:Article (context),context|]]
[[:Bar:Article (context), context|]]
[[:Bar:Article (context),context|]]
-!! html
+!! html/php
[[Article (context), context|Article]]
[[Article (context),context|Article]]
[[Bar:Article (context), context|Article]]
@@ -11543,7 +12285,7 @@ Empty lines are trimmed
-!! html
+!! html/php
Empty lines are trimmed
!! end
@@ -11556,7 +12298,7 @@ pst
* <noinclude>~~~</noinclude>
* <includeonly>~~~</includeonly>
* <onlyinclude>~~~</onlyinclude>
-!! html
+!! html/php
* [[Special:Contributions/127.0.0.1|127.0.0.1]]
* <noinclude>[[Special:Contributions/127.0.0.1|127.0.0.1]]</noinclude>
* <includeonly>[[Special:Contributions/127.0.0.1|127.0.0.1]]</includeonly>
@@ -11587,7 +12329,7 @@ As well as inside noinclude/onlyinclude
But not inside includeonly
<includeonly>{{subst:Foo}}</includeonly>
-!! html
+!! html/php
Shall not expand:
<nowiki>~~~~</nowiki>
@@ -11642,7 +12384,7 @@ parsoid=wt2html
Parsoid: Escape nowiki with trailing space in tags
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p>&lt;nowiki &gt; foo &lt/nowiki ></p>
<p>a&lt;nowiki /&gt;b</p>
<p>c&lt;nowiki/ &gt;d</p>
@@ -11658,7 +12400,7 @@ c&lt;nowiki/ &gt;d
Parsoid: Escape weird noWikI capitalizations
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p>&lt;noWikI &gt; foo &lt/NoWikI ></p>
!! wikitext
&lt;noWikI &gt; foo &lt;/NoWikI &gt;
@@ -11921,7 +12663,7 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:139px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" width="137" height="16" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/206px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/274px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is a caption</div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["width",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[24,38,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;137px&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">137px&lt;/span>"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137"/></a><figcaption>This is a caption</figcaption></figure>
+<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["width",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[24,38,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;137px&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">137px&lt;/span>"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137"/></a><figcaption>This is a caption</figcaption></figure>
!! end
!! test
@@ -11932,7 +12674,7 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:139px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" width="137" height="16" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/206px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/274px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is a caption</div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["thumbnail",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[18,32,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;thumb&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">thumb&lt;/span>"}],["width",{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[33,47,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;137px&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">137px&lt;/span>"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137"/></a><figcaption>This is a caption</figcaption></figure>
+<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["thumbnail",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[18,32,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;thumb&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">thumb&lt;/span>"}],["width",{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[33,47,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;137px&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">137px&lt;/span>"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137"/></a><figcaption>This is a caption</figcaption></figure>
!! end
!! test
@@ -11989,7 +12731,7 @@ thumbsize=220
!! html/parsoid
<p>123<span class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span>456</p>
<p>123</p><figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure><p>456</p>
-<p>123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></figure><p>456</p>
+<p>123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></figure><p>456</p>
!! end
!! test
@@ -12011,7 +12753,7 @@ Image with multiple widths -- use last
<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" width="300" height="34" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/450px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/600px-Foobar.jpg 2x" /></a>
</p>
!! html/parsoid
-<p><span typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></span></p>
+<p><span typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></span></p>
!! end
!! test
@@ -12027,7 +12769,7 @@ thumbsize=220
<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="caption" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" style="vertical-align: middle" /></a>
</p>
!! html/parsoid
-<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
<p><span class="mw-default-size mw-valign-middle" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
@@ -12043,9 +12785,9 @@ Image with width attribute at different positions
<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div>
!! html/parsoid
-<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
-<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
-<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
+<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
+<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
+<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
!! end
# a sad bit of backward-compatibility
@@ -12061,7 +12803,7 @@ parsoid=wt2html,wt2wt,html2html
<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/177px-Foobar.jpg" width="177" height="20" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/265px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/353px-Foobar.jpg 2x" /></a>
</p>
!! html/parsoid
-<p><span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="2" width="20"/></a></span> <span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="20" width="177"/></a></span></p>
+<p><span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="2" width="20"/></a></span> <span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/177px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="20" width="177"/></a></span></p>
!! end
!! test
@@ -12100,6 +12842,21 @@ Image with link parameter, protocol-less URL target
!! end
!! test
+Escaping non-block captions (T107435)
+!! options
+parsoid={
+ "modes": ["wt2wt"],
+ "changes": [
+ ["[typeof~='mw:Image']", "attr", "data-mw", "{\"caption\": \"|\"}"]
+ ]
+}
+!! wikitext
+[[Image:Foobar.jpg|caption]]
+!! wikitext/edited
+[[Image:Foobar.jpg|<nowiki>|</nowiki>]]
+!! end
+
+!! test
Image with link parameter, wgExternalLinkTarget
!! wikitext
[[Image:foobar.jpg|link=http://example.com/]]
@@ -12187,7 +12944,7 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="http://example.com/"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="http://example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="http://example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>Title</figcaption></figure>
!! end
!! test
@@ -12287,8 +13044,6 @@ parsoid=wt2html,wt2wt,html2html
!! test
Image with wiki markup in implicit alt
-!! options
-parsoid=wt2html,wt2wt,html2html
!! wikitext
[[Image:Foobar.jpg|testing '''bold''' in alt]]
@@ -12298,8 +13053,8 @@ parsoid=wt2html,wt2wt,html2html
</p><p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="testing bold in alt" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw="{&quot;caption&quot;:&quot;testing '''bold''' in alt&quot;}"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
-<p><span class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="testing bold in alt" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"testing &lt;b data-parsoid=\"{&amp;quot;dsr&amp;quot;:[27,37,3,3]}\">bold&lt;/b> in alt"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="testing bold in alt" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"testing bold in alt","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=testing &#39;&#39;&#39;bold&#39;&#39;&#39; in alt","resource":"Image:Foobar.jpg"}}'/></a></span></p>
!! end
!! test
@@ -12334,9 +13089,9 @@ parsoid=wt2html,wt2wt,html2html
</p><p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
-<p><span class="mw-default-size" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
-<p><span class="mw-default-size" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
!! end
!! test
@@ -12372,15 +13127,15 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
!! end
###################
# Image sizing.
# See https://www.mediawiki.org/wiki/Help:Images#Size_and_frame
-# and https://bugzilla.wikimedia.org/show_bug.cgi?id=62258
+# and https://phabricator.wikimedia.org/T64258
# Foobar has actual size of 1941x220
# 1. Thumbs & frameless always reduce, can't be enlarged unless it's
# a scalable format.
@@ -12401,8 +13156,8 @@ parsoid=wt2html,wt2wt,html2html
</p><p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="2000" height="227" class="thumbborder" /></a>
</p>
!! html/parsoid
-<p><span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="227" width="2000"/></a></span></p>
-<p><span class="mw-image-border" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="227" width="2000"/></a></span></p>
+<p><span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1941px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="227" width="2000"/></a></span></p>
+<p><span class="mw-image-border" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1941px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="227" width="2000"/></a></span></p>
!! end
!! test
@@ -12418,8 +13173,8 @@ parsoid=wt2html,wt2wt,html2html
</p><p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/1000px-Foobar.jpg" width="1000" height="113" class="thumbborder" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/1500px-Foobar.jpg 1.5x, http://example.com/images/3/3a/Foobar.jpg 2x" /></a>
</p>
!! html/parsoid
-<p><span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="113" width="1000"/></a></span></p>
-<p><span class="mw-image-border" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="113" width="1000"/></a></span></p>
+<p><span typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1000px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="113" width="1000"/></a></span></p>
+<p><span class="mw-image-border" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1000px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="113" width="1000"/></a></span></p>
!! end
!! test
@@ -12432,7 +13187,7 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:52px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" width="50" height="6" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/75px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/100px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></figure>
!! end
!! test
@@ -12448,8 +13203,8 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:2002px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" width="2000" height="1500" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/3000px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/4000px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div></div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/f/ff/Foobar.svg" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1941px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/240px-Foobar.svg" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a></figure>
!! end
!! test
@@ -12462,7 +13217,7 @@ parsoid=wt2html,wt2wt,html2html
<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" width="50" height="6" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/75px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/100px-Foobar.jpg 2x" /></a>
</p>
!! html/parsoid
-<p><span typeof="mw:Image/Frameless"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
+<p><span typeof="mw:Image/Frameless"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
!! end
!! test
@@ -12478,8 +13233,8 @@ parsoid=wt2html,wt2wt,html2html
</p><p><a href="/wiki/File:Foobar.svg" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" width="2000" height="1500" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/3000px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/4000px-Foobar.svg.png 2x" /></a>
</p>
!! html/parsoid
-<p><span typeof="mw:Image/Frameless"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
-<p><span typeof="mw:Image/Frameless"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/f/ff/Foobar.svg" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a></span></p>
+<p><span typeof="mw:Image/Frameless"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1941px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span typeof="mw:Image/Frameless"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/240px-Foobar.svg" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a></span></p>
!! end
!! test
@@ -12537,7 +13292,7 @@ Frameless image caption with a free URL
<p><a href="/wiki/File:Foobar.jpg" class="image" title="http://example.com"><img alt="http://example.com" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"http://example.com"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&lt;a rel=\"mw:ExtLink\" href=\"http://example.com\" data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;url&amp;quot;,&amp;quot;dsr&amp;quot;:[18,36,0,0]}\">http://example.com&lt;/a>"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -12550,7 +13305,7 @@ thumbsize=220
<div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" href="http://example.com">http://example.com</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" href="http://example.com">http://example.com</a></figcaption></figure>
!! end
!! test
@@ -12564,7 +13319,7 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Alteration" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img alt="Alteration" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" href="http://example.com">http://example.com</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img alt="Alteration" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" href="http://example.com">http://example.com</a></figcaption></figure>
!! end
!! test
@@ -12576,7 +13331,7 @@ SVG thumbnails with no language set
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" width="180" height="135" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/f/ff/Foobar.svg" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/220px-Foobar.svg" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>caption</figcaption></figure>
!! end
!! test
@@ -12589,7 +13344,7 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=File:Foobar.svg&amp;lang=de" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.png" width="180" height="135" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/f/ff/Foobar.svg" lang="de" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/220px-Foobar.svg" lang="de" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>caption</figcaption></figure>
!! end
!! test
@@ -12613,7 +13368,7 @@ BUG 1887: A ISBN with a thumbnail
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a href="/wiki/Special:BookSources/1235467890" class="internal mw-magiclink-isbn">ISBN 1235467890</a></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="Special:BookSources/1235467890" rel="mw:ExtLink">ISBN 1235467890</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="./Special:BookSources/1235467890" rel="mw:WikiLink">ISBN 1235467890</a></figcaption></figure>
!! end
!! test
@@ -12624,7 +13379,7 @@ BUG 1887: A RFC with a thumbnail
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is <a href="//tools.ietf.org/html/rfc12354" rel="mw:ExtLink">RFC 12354</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is <a href="//tools.ietf.org/html/rfc12354" rel="mw:ExtLink">RFC 12354</a></figcaption></figure>
!! end
!! test
@@ -12635,7 +13390,7 @@ BUG 1887: A mailto link with a thumbnail
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Please <a rel="nofollow" class="external free" href="mailto:nobody@example.com">mailto:nobody@example.com</a></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>Please <a rel="mw:ExtLink" href="mailto:nobody@example.com">mailto:nobody@example.com</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>Please <a rel="mw:ExtLink" href="mailto:nobody@example.com">mailto:nobody@example.com</a></figcaption></figure>
!! end
# Pending resolution to bug 368
@@ -12647,7 +13402,7 @@ BUG 648: Frameless image caption with a link
<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a link in it"><img alt="text with a link in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a [[link]] in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a &lt;a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;simple&amp;quot;,&amp;quot;a&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;./Link&amp;quot;},&amp;quot;sa&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;link&amp;quot;},&amp;quot;dsr&amp;quot;:[30,38,2,2]}\">link&lt;/a> in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -12658,7 +13413,7 @@ BUG 648: Frameless image caption with a link (suffix)
<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a linkfoo in it"><img alt="text with a linkfoo in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a [[link]]foo in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a &lt;a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;simple&amp;quot;,&amp;quot;a&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;./Link&amp;quot;},&amp;quot;sa&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;link&amp;quot;},&amp;quot;dsr&amp;quot;:[30,41,2,5],&amp;quot;tail&amp;quot;:&amp;quot;foo&amp;quot;}\">linkfoo&lt;/a> in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -12669,7 +13424,7 @@ BUG 648: Frameless image caption with an interwiki link
<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a MeatBall:Link in it"><img alt="text with a MeatBall:Link in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a [[MeatBall:Link]] in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a &lt;a rel=\"mw:ExtLink\" href=\"http://www.usemod.com/cgi-bin/mb.pl?Link\" title=\"meatball:Link\" data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;simple&amp;quot;,&amp;quot;a&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;http://www.usemod.com/cgi-bin/mb.pl?Link&amp;quot;},&amp;quot;sa&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;MeatBall:Link&amp;quot;},&amp;quot;isIW&amp;quot;:true,&amp;quot;dsr&amp;quot;:[30,47,2,2]}\">MeatBall:Link&lt;/a> in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -12680,7 +13435,15 @@ BUG 648: Frameless image caption with a piped interwiki link
<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a link in it"><img alt="text with a link in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a [[MeatBall:Link|link]] in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"text with a &lt;a rel=\"mw:ExtLink\" href=\"http://www.usemod.com/cgi-bin/mb.pl?Link\" title=\"meatball:Link\" data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;piped&amp;quot;,&amp;quot;a&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;http://www.usemod.com/cgi-bin/mb.pl?Link&amp;quot;},&amp;quot;sa&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;MeatBall:Link&amp;quot;},&amp;quot;isIW&amp;quot;:true,&amp;quot;dsr&amp;quot;:[30,52,16,2]}\">link&lt;/a> in it"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+!! end
+
+!! test
+T107474: Frameless image caption with <nowiki>
+!! wikitext
+[[File:Foobar.jpg|<nowiki>text with a [[MeatBall:Link|link]] in it</nowiki>]]
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&lt;span typeof=\"mw:Nowiki\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[18,75,8,9]}\">text with a [[MeatBall:Link|link]] in it&lt;/span>"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -12691,7 +13454,7 @@ Escape HTML special chars in image alt text
<p><a href="/wiki/File:Foobar.jpg" class="image" title="&amp; &lt; &gt; &quot;"><img alt="&amp; &lt; &gt; &quot;" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&amp; &lt; > \""}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&amp;amp; &amp;lt; &amp;gt; \""}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -12702,7 +13465,7 @@ BUG 499: Alt text should have &#1234;, not &amp;1234;
<p><a href="/wiki/File:Foobar.jpg" class="image" title="♀"><img alt="♀" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&amp;#9792;"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&lt;span typeof=\"mw:Entity\" data-parsoid=\"{&amp;quot;src&amp;quot;:&amp;quot;&amp;amp;#9792;&amp;quot;,&amp;quot;srcContent&amp;quot;:&amp;quot;♀&amp;quot;,&amp;quot;dsr&amp;quot;:[18,25,null,null]}\">♀&lt;/span>"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -12726,7 +13489,7 @@ Image caption containing another image
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is a caption with another <a href="/wiki/File:Thumb.png" class="image" title="image"><img alt="image" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" /></a> inside it!</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is a caption with another <span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"image"}'><a href="./File:Thumb.png"><img resource="./File:Thumb.png" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a></span> inside it!</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is a caption with another <span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"image"}'><a href="./File:Thumb.png"><img resource="./File:Thumb.png" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a></span> inside it!</figcaption></figure>
!! end
!! test
@@ -12750,7 +13513,7 @@ Image: caption containing leading space
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>bar</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption> bar</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption> bar</figcaption></figure>
!!end
!! test
@@ -12769,7 +13532,7 @@ and some more text.]]
<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is an example image thumbnail caption with a table <table> <tr> <th> Foo </th> <th> Bar </th></tr> <tr> <td> Foo1 </td> <td> Bar1 </td></tr></table> and some more text.</div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This is an example image thumbnail caption with a table
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This is an example image thumbnail caption with a table
<table>
<tbody>
<tr><th>Foo </th><th>Bar</th></tr>
@@ -12786,7 +13549,7 @@ Bug 3090: External links other than http: in image captions
<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This caption has <a rel="nofollow" class="external text" href="irc://example.net">irc</a> and <a rel="nofollow" class="external text" href="https://example.com">Secure</a> ext links in it.</div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This caption has <a rel="mw:ExtLink" href="irc://example.net">irc</a> and <a rel="mw:ExtLink" href="https://example.com">Secure</a> ext links in it.</figcaption></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This caption has <a rel="mw:ExtLink" href="irc://example.net">irc</a> and <a rel="mw:ExtLink" href="https://example.com">Secure</a> ext links in it.</figcaption></figure>
!! end
!! test
@@ -12828,7 +13591,7 @@ language=es
<div class="thumb tleft"><div class="thumbinner" style="width:222px;"><a href="/wiki/Foo" title="Foo"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/Archivo:Foobar.jpg" class="internal" title="Aumentar"></a></div>caption</div></div></div>
!! html/parsoid
-<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./Foo"><img resource="./Archivo:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="Foo"><img resource="./Archivo:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
!! end
!! test
@@ -12842,7 +13605,7 @@ parsoid=wt2html,wt2wt,html2html
<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="extra thumbborder" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>
</p>
!! html/parsoid
-<p><span class="mw-default-size mw-image-border extra" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
+<p><span class="mw-default-size mw-image-border extra" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></span></p>
!! end
# Note that 'right' is the default alignment, despite the misspelled 'righ' below
@@ -12863,9 +13626,9 @@ parsoid=wt2html,wt2wt,html2html
<div class="thumb tleft"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
!! html/parsoid
-<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
-<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
!! end
!! article
@@ -12910,7 +13673,7 @@ Parsoid-specific image handling - simple image with size and middle alignment
!! wikitext
[[File:Foobar.jpg|middle|50px]]
!! html/parsoid
-<p><span class="mw-valign-middle" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
+<p><span class="mw-valign-middle" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
!! end
!! test
@@ -12921,7 +13684,7 @@ parsoid=wt2wt,wt2html,html2html
!! wikitext
[[Image:Foobar.jpg|middle|50px]]
!! html/parsoid
-<p><span class="mw-valign-middle" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
+<p><span class="mw-valign-middle" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
!! end
!! test
@@ -12930,7 +13693,7 @@ Parsoid-specific image handling - simple image with size and middle alignment
!! wikitext
[[File:Foobar.jpg|50px|middle]]
!! html/parsoid
-<p><span class="mw-valign-middle" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"50px"},{"ck":"middle","ak":"middle"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+<p><span class="mw-valign-middle" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"50px"},{"ck":"middle","ak":"middle"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
!! end
!! test
@@ -12941,7 +13704,7 @@ parsoid=wt2html,wt2wt,html2html
!! wikitext
[[Image:Foobar.jpg|50px|middle]]
!! html/parsoid
-<p><span class="mw-valign-middle" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
+<p><span class="mw-valign-middle" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></span></p>
!! end
!! test
@@ -12965,7 +13728,7 @@ Parsoid-specific image handling - thumbnail with halign, valign, and caption
!! wikitext
[[File:Foobar.jpg|left|baseline|thumb|caption content]]
!! html/parsoid
-<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption content</figcaption></figure>
+<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption content</figcaption></figure>
!! end
!! test
@@ -12974,7 +13737,7 @@ Parsoid-specific image handling - thumbnail with halign, valign, and caption
!! wikitext
[[File:Foobar.jpg|thumb|left|baseline|caption content]]
!! html/parsoid
-<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption content"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption content</figcaption></figure>
+<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption content"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption content</figcaption></figure>
!! end
!! test
@@ -12982,7 +13745,7 @@ Parsoid-specific image handling - thumbnail with specific size, halign, valign,
!! wikitext
[[Image:Foobar.jpg|right|middle|thumb|50x50px|caption]]
!! html/parsoid
-<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a><figcaption>caption</figcaption></figure>
!! end
!! test
@@ -13029,7 +13792,7 @@ Parsoid-specific image handling - simple image with a formatted caption
!! wikitext
[[File:Foobar.jpg|<table><tr><td>a</td><td>b</td></tr><tr><td>c</td></tr></table>]]
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&lt;table>&lt;tr>&lt;td>a&lt;/td>&lt;td>b&lt;/td>&lt;/tr>&lt;tr>&lt;td>c&lt;/td>&lt;/tr>&lt;/table>"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&lt;table data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;html&amp;quot;,&amp;quot;dsr&amp;quot;:[18,81,7,8]}\">&lt;tbody data-parsoid=\"{&amp;quot;dsr&amp;quot;:[25,73,0,0]}\">&lt;tr data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;html&amp;quot;,&amp;quot;dsr&amp;quot;:[25,54,4,5]}\">&lt;td data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;html&amp;quot;,&amp;quot;dsr&amp;quot;:[29,39,4,5]}\">a&lt;/td>&lt;td data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;html&amp;quot;,&amp;quot;dsr&amp;quot;:[39,49,4,5]}\">b&lt;/td>&lt;/tr>&lt;tr data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;html&amp;quot;,&amp;quot;dsr&amp;quot;:[54,73,4,5]}\">&lt;td data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;html&amp;quot;,&amp;quot;dsr&amp;quot;:[58,68,4,5]}\">c&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
!! end
!! test
@@ -13050,7 +13813,7 @@ foo
bar
!! html/parsoid
<p>foo</p>
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This caption has a <center>unbalanced tag in it.</center></figcaption></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This caption has a <center>unbalanced tag in it.</center></figcaption></figure>
<p>bar</p>
!! end
@@ -13061,7 +13824,7 @@ parsoid=wt2html,wt2wt
!! wikitext
[[File:Foobar.jpg|thumb|]]
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption></figcaption></figure>
!! end
# empty captions don't get serialized unless we're in the "round trip" case
@@ -13088,7 +13851,7 @@ Parsoid-specific image handling - whitespace caption
!! wikitext
[[File:Foobar.jpg|thumb| ]]
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption> </figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption> </figcaption></figure>
!! end
!! test
@@ -13103,6 +13866,42 @@ bar
bar</p>
!! end
+## Edge case bugs in Parsoid from T93580
+!! test
+T93580: 1. Templated <ref> inside block images
+!! wikitext
+[[File:Foobar.jpg|thumb|Caption with templated ref: {{echo|<ref>foo</ref>}}]]
+
+<references />
+!! html/parsoid
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption with templated ref: {{echo|&lt;ref>foo&lt;/ref>}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption with templated ref: <span about="#mwt5" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo&lt;/ref>"}},"i":0}}]}'><a href="#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></span></figcaption></figure>
+
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+!! end
+
+!! test
+T93580: 2. <ref> inside inline images
+!! wikitext
+[[File:Foobar.jpg|Undisplayed caption in inline image with ref: <ref>foo</ref>]]
+
+<references />
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: &lt;ref>foo&lt;/ref>"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;span about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[64,78,5,6]}\" data-mw=\"{&amp;quot;name&amp;quot;:&amp;quot;ref&amp;quot;,&amp;quot;body&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;mw-reference-text-cite_note-1&amp;quot;},&amp;quot;attrs&amp;quot;:{}}\">&lt;a href=\"#cite_note-1\" style=\"counter-reset: mw-Ref 1;\">&lt;span class=\"mw-reflink-text\">[1]&lt;/span>&lt;/a>&lt;/span>&lt;meta typeof=\"mw:Extension/ref/Marker\" about=\"#mwt2\" data-parsoid=\"{&amp;quot;group&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;foo&amp;quot;,&amp;quot;hasRefInRef&amp;quot;:false,&amp;quot;dsr&amp;quot;:[64,78,5,6],&amp;quot;tmp&amp;quot;:{}}\" data-mw=\"{}\">"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+!! end
+
+!! test
+T93580: 3. Templated <ref> inside inline images
+!! wikitext
+[[File:Foobar.jpg|Undisplayed caption in inline image with ref: {{echo|<ref>{{echo|foo}}</ref>}}]]
+
+<references />
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: {{echo|&lt;ref>{{echo|foo}}&lt;/ref>}}"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;span about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Transclusion mw:Extension/ref\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[64,96,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;&lt;ref>{{echo|foo}}&lt;/ref>&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">&lt;a href=\"#cite_note-1\" style=\"counter-reset: mw-Ref 1;\">&lt;span class=\"mw-reflink-text\">[1]&lt;/span>&lt;/a>&lt;/span>&lt;meta typeof=\"mw:Transclusion mw:Extension/ref/Marker\" about=\"#mwt2\" data-parsoid=\"{&amp;quot;group&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;foo&amp;quot;,&amp;quot;hasRefInRef&amp;quot;:false,&amp;quot;dsr&amp;quot;:[64,96,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;tmp&amp;quot;:{}}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;&lt;ref>{{echo|foo}}&lt;/ref>&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+!! end
###
### Subpages
@@ -13435,6 +14234,152 @@ Bar
</p>
!! end
+## The whitespace on the empty line is part of the test. Please do not delete
+!! test
+1. Categories and newlines: All preceding newlines should be suppressed (courtesy bug 87)
+!! options
+parsoid=wt2html,wt2wt
+!! wikitext
+This
+
+[[Category:Foo]] and this should be part of same paragraph (not an indent-pre)
+
+{{echo|[[Category:Foo]] and so should this!}}
+!! html
+<p>This and this should be part of same paragraph (not an indent-pre) and so should this!
+</p>
+!! html/parsoid
+<p>This
+
+<link rel="mw:PageProp/Category" href="./Category:Foo"/> and this should be part of same paragraph (not an indent-pre)
+
+<link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Foo]] and so should this!"}},"i":0}}]}'/><span about="#mwt1"> and so should this!</span></p>
+!! end
+
+## Parsoid will not try to wt2wt this while preserving newlines because
+## it suppresses excess newlines within list items -- and we don't want to
+## introduce a special case just for categories, which is, in reality somewhat
+## odd behavior -- categories are unlikely to be used in list items like this
+## in top-level pages and are only likely to show up in template-generated
+## list items where this RT-ing is a non-issue.
+##
+## The whitespace on the empty line is part of the test. Please do not delete
+!! test
+2. Categories and newlines: All preceding newlines should be suppressed (courtesy bug 87)
+!! options
+parsoid=wt2html
+!! wikitext
+* This
+
+[[Category:Foo]] and this should be part of the same list item
+* So should this
+
+{{echo|[[Category:Foo]] and this should be part of the same list item}}
+!! html
+<ul><li>This and this should be part of the same list item</li>
+<li>So should this and this should be part of the same list item</li></ul>
+!! html/parsoid
+<ul>
+<li>This <link rel="mw:PageProp/Category" href="./Category:Foo"/> and this should be part of the same list item</li>
+<li>So should this <link rel="mw:PageProp/Category" href="./Category:Foo" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Foo]] and this should be part of the same list item"}},"i":0}}]}'/><span> and this should be part of the same list item</span></li>
+</ul>
+!! end
+
+## Newlines and categories that follow the last item of a list
+## are treated differently because this (list followed by categories)
+## is an extremely common pattern on wikis.
+!! test
+3. Categories and newlines: newline suppression for last list item should RT properly
+!! wikitext
+* a
+* b
+
+[[Category:Foo]]
+
+[[Category:Bar]]
+[[Category:Baz]]
+!! html/parsoid
+<ul><li> a</li>
+<li> b</li></ul>
+
+<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
+
+<link rel="mw:PageProp/Category" href="./Category:Bar" data-parsoid='{"stx":"simple","a":{"href":"./Category:Bar"},"sa":{"href":"Category:Bar"}}'/>
+<link rel="mw:PageProp/Category" href="./Category:Baz" data-parsoid='{"stx":"simple","a":{"href":"./Category:Baz"},"sa":{"href":"Category:Baz"}}'/>
+!! end
+
+!! test
+4. Categories and newlines: newline suppression for last list item should RT properly
+!! wikitext
+* a
+**** b
+
+[[Category:Foo]]
+!! html/parsoid
+<ul><li> a
+<ul><li><ul><li><ul><li> b</li></ul></li></ul></li></ul></li></ul>
+
+<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
+!! end
+
+## only wt2html for this to make sure the algo only applies to the rightmost path
+!! test
+5. Categories and newlines: migrateTrailingCategories dom pass should only run on the rightmost path of nested lists
+!! options
+parsoid=wt2html
+!! wikitext
+* a
+** b
+[[Category:Foo]]
+* c
+** d
+[[Category:Foo]]
+!! html/parsoid
+<ul><li> a
+<ul><li> b
+<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul></li>
+<li> c
+<ul><li> d</li></ul></li></ul>
+<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
+!! end
+
+!! test
+6. Categories and newlines: migrateTrailingCategories dom pass should not migrate categories not preceded by newlines
+!! wikitext
+* a [[Category:Foo]]
+!! html/parsoid
+<ul><li>a <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
+!! end
+
+# This test also demonstrates because of newline+category tunneling
+# through the list hander, template wrapping doesn't expand to the
+# containing list when the list item swallows the category.
+!! test
+7. Categories and newlines: migrateTrailingCategories dom pass should leave template content alone
+!! wikitext
+* {{echo|a
+[[Category:Foo]]}}
+!! html/parsoid
+<ul><li> <span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n[[Category:Foo]]"}},"i":0}}]}'>a</span><span about="#mwt1">
+</span><link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
+!! end
+
+!! test
+8. Categories and newlines: migrateTrailingCategories dom pass should not get tripped by intervening templates
+!! wikitext
+* a
+
+{{echo|[[Category:Foo]]
+[[Category:Bar]]}}
+[[Category:Baz]]
+!! html/parsoid
+<ul><li> a</li></ul>
+
+<link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"},"pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Foo]]\n[[Category:Bar]]"}},"i":0}}]}'/><span about="#mwt1">
+</span><link rel="mw:PageProp/Category" href="./Category:Bar" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Category:Bar"},"sa":{"href":"Category:Bar"}}'/>
+<link rel="mw:PageProp/Category" href="./Category:Baz" data-parsoid='{"stx":"simple","a":{"href":"./Category:Baz"},"sa":{"href":"Category:Baz"}}'/>
+!! end
+
!! test
Parsoid: Serialize link to category page with colon escape
!! options
@@ -13445,20 +14390,26 @@ parsoid
[[:Category:Foo|Bar]]
!! html
<p>
-<a rel="mw:WikiLink" href="Category:Foo" title="Category:Foo">Category:Foo</a>
-<a rel="mw:WikiLink" href="Category:Foo" title="Category:Foo">Bar</a>
+<a rel="mw:WikiLink" href="./Category:Foo" title="Category:Foo">Category:Foo</a>
+<a rel="mw:WikiLink" href="./Category:Foo" title="Category:Foo">Bar</a>
</p>
!! end
+# html2wt localizes the "Category" namespace.
+# XXX the <link> element needs an empty data-parsoid attribute, or
+# else the html2html test fails because spaces are inserted.
!! test
-Parsoid: Link prefix/suffixes aren't applied to category links
+Link prefix/suffixes aren't applied to category links
!! options
parsoid=wt2html,wt2wt,html2html
language=is
!! wikitext
x[[Category:Foo]]y
-!! html
-<p>x<link rel="mw:PageProp/Category" href="Category:Foo">y</p>
+!! html/php
+<p>xy
+</p>
+!! html/parsoid
+<p>x<link rel="mw:PageProp/Category" href="./Flokkur:Foo" data-parsoid=""/>y</p>
!! end
!! test
@@ -13484,15 +14435,15 @@ parsoid
[[Category:Foo]]
[[Category:Foo|Bar]]
!! html
-<link rel="mw:PageProp/Category" href="Category:Foo">
-<link rel="mw:PageProp/Category" href="Category:Foo#Bar">
+<link rel="mw:PageProp/Category" href="./Category:Foo">
+<link rel="mw:PageProp/Category" href="./Category:Foo#Bar">
!! end
!! test
Normalize hrefs properly before testing for invalid link targets (bug 70894)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<link rel="mw:PageProp/Category" href="./Category:Toxine_bactérienne"/>
!! wikitext
[[Category:Toxine bactérienne]]
@@ -13630,7 +14581,7 @@ __FORCETOC__
== Headline ==
== Headline 2 ==
== Headline ==
-!! html
+!! html/php
<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
<ul>
<li class="toclevel-1 tocsection-1"><a href="#Headline_2"><span class="tocnumber">1</span> <span class="toctext">Headline 2</span></a></li>
@@ -13745,6 +14696,22 @@ TOC regression (T11764)
!! end
!! test
+TOC for heading containing <span id="..."></span> (T96153)
+!! wikitext
+__FORCETOC__
+==<span id="old-anchor"></span>New title==
+!! html/php
+<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#New_title"><span class="tocnumber">1</span> <span class="toctext">New title</span></a></li>
+</ul>
+</div>
+
+<h2><span class="mw-headline" id="New_title"><span id="old-anchor"></span>New title</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: New title">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+
+!! end
+
+!! test
TOC with wgMaxTocLevel=3 (bug 6204)
!! options
wgMaxTocLevel=3
@@ -14376,11 +15343,8 @@ I always thought &xacute; was a cute letter.
</p>
!! end
-# TODO: generalize to PHP parser?
!! test
HTML5 tags
-!! options
-parsoid
!! wikitext
<data value="5">five</data>
<time datetime="2000-01-01T00:00Z">The new millenium started</time>
@@ -14388,7 +15352,8 @@ parsoid
!! html
<p><data value="5">five</data>
<time datetime="2000-01-01T00:00Z">The new millenium started</time>
-<mark>This highlighted text</mark></p>
+<mark>This highlighted text</mark>
+</p>
!! end
!! test
@@ -14628,13 +15593,19 @@ Attribute test: unquoted but illegal value (hash)
</p>
!! end
+# Parsoid does not serialize to empty attribute syntax,
+# so wt2wt and html2wt cases are skipped
!! test
-Attribute test: no value
+Attribute test: no value (T54330)
+!! options
+parsoid=wt2html,html2html
!! wikitext
<font color>foo</font>
-!! html
-<p><font color="color">foo</font>
+!! html/php
+<p><font color="">foo</font>
</p>
+!! html/parsoid
+<p><font color="">foo</font></p>
!! end
!! test
@@ -14932,6 +15903,7 @@ MSIE 6 CSS safety test: sup/sub script (bug 55332)
!! end
+# FIXME: Parsoid fails to sanitize this! See T58846.
!! test
Opera -o-link CSS
!! wikitext
@@ -15006,7 +15978,7 @@ CSS line continuation 2
!! wikitext
<div style="background-image: u\&#13;rl(test.jpg); "></div>
!! html
-<div style="/* insecure input */"></div>
+<div style="/* invalid control char */"></div>
!! end
@@ -15063,7 +16035,7 @@ evil <math>-wiki-tags without Extension:Math enabled
Parser hook: empty input
!! wikitext
<tag></tag>
-!! html
+!! html/php
<pre>
''
array (
@@ -15076,7 +16048,7 @@ array (
Parser hook: empty input using terminated empty elements
!! wikitext
<tag/>
-!! html
+!! html/php
<pre>
NULL
array (
@@ -15089,7 +16061,7 @@ array (
Parser hook: empty input using terminated empty elements (space before)
!! wikitext
<tag />
-!! html
+!! html/php
<pre>
NULL
array (
@@ -15102,7 +16074,7 @@ array (
Parser hook: basic input
!! wikitext
<tag>input</tag>
-!! html
+!! html/php
<pre>
'input'
array (
@@ -15116,7 +16088,7 @@ array (
Parser hook: case insensitive
!! wikitext
<TAG>input</TAG>
-!! html
+!! html/php
<pre>
'input'
array (
@@ -15130,7 +16102,7 @@ array (
Parser hook: case insensitive, redux
!! wikitext
<TaG>input</TAg>
-!! html
+!! html/php
<pre>
'input'
array (
@@ -15145,7 +16117,7 @@ Parser hook: nested tags
noxml
!! wikitext
<tag><tag></tag></tag>
-!! html
+!! html/php
<pre>
'<tag>'
array (
@@ -15158,14 +16130,14 @@ array (
Parser hook: basic arguments
!! wikitext
<tag width=200 height = "100" depth = '50' square></tag>
-!! html
+!! html/php
<pre>
''
array (
'width' => '200',
'height' => '100',
'depth' => '50',
- 'square' => 'square',
+ 'square' => '',
)
</pre>
@@ -15175,7 +16147,7 @@ array (
Parser hook: argument containing a forward slash (bug 5344)
!! wikitext
<tag filename='/tmp/bla'></tag>
-!! html
+!! html/php
<pre>
''
array (
@@ -15189,7 +16161,7 @@ array (
Parser hook: empty input using terminated empty elements (bug 2374)
!! wikitext
<tag foo=bar/>text
-!! html
+!! html/php
<pre>
NULL
array (
@@ -15206,14 +16178,14 @@ Parser hook: basic arguments using terminated empty elements (bug 2374)
<tag width=200 height = "100" depth = '50' square/>
other stuff
</tag>
-!! html
+!! html/php
<pre>
NULL
array (
'width' => '200',
'height' => '100',
'depth' => '50',
- 'square' => 'square',
+ 'square' => '',
)
</pre>
<p>other stuff
@@ -15230,7 +16202,7 @@ Parser hook: static parser hook not inside a comment
!! wikitext
<statictag>hello, world</statictag>
<statictag action=flush/>
-!! html
+!! html/php
<p>hello, world
</p>
!! end
@@ -15241,7 +16213,7 @@ Parser hook: static parser hook inside a comment
!! wikitext
<!-- <statictag>hello, world</statictag> -->
<statictag action=flush/>
-!! html
+!! html/php
<p><br />
</p>
!! end
@@ -15300,20 +16272,24 @@ Sanitizer: Closing of open but not closed tags
!! test
Sanitizer: Closing of closed but not open tags
+!! options
+parsoid=wt2html
!! wikitext
</s>
-!! html
-<p>&lt;/s&gt;
-</p>
+!! html/php+tidy
+!! html/parsoid
!! end
!! test
Sanitizer: Closing of closed but not open table tags
+!! options
+parsoid=wt2html
!! wikitext
Table not started</td></tr></table>
-!! html
-<p>Table not started&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
-</p>
+!! html/php+tidy
+<p>Table not started</p>
+!! html/parsoid
+<p>Table not started</p>
!! end
!! test
@@ -15360,7 +16336,7 @@ Sanitizer: Validating that <meta> and <link> work, but only for Microdata
<link rel="stylesheet" itemprop="hello" href="{{SERVER}}">
</div>
!! html
-<div itemscope="itemscope">
+<div itemscope="">
<p> <meta itemprop="hello" content="world" />
&lt;meta http-equiv="refresh" content="5"&gt;
<meta itemprop="hello" content="5" />
@@ -16112,7 +17088,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
!! end
@@ -16132,7 +17108,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
==a==
===aa===
====aaa====
@@ -16154,7 +17130,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
===aa===
====aaa====
!! end
@@ -16175,7 +17151,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
====aaa====
!! end
@@ -16195,7 +17171,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
==b==
===ba===
===bb===
@@ -16219,7 +17195,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
===ba===
!! end
@@ -16239,7 +17215,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
===bb===
====bba====
!! end
@@ -16260,7 +17236,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
====bba====
!! end
@@ -16280,7 +17256,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
===bc===
!! end
@@ -16300,7 +17276,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
==c==
===ca===
!! end
@@ -16321,7 +17297,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
===ca===
!! end
@@ -16341,7 +17317,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
!! end
!! test
@@ -16352,7 +17328,7 @@ section=1
==a==
==bogus== not a legal section
==b==
-!! html
+!! html/php
==a==
==bogus== not a legal section
!! end
@@ -16365,7 +17341,7 @@ section=2
==a==
==bogus== not a legal section
==b==
-!! html
+!! html/php
==b==
!! end
@@ -16377,7 +17353,7 @@ section=1
==a==
==b== <!-- -->
==c==
-!! html
+!! html/php
==a==
!! end
@@ -16389,7 +17365,7 @@ section=2
==a==
==b== <!-- -->
==c==
-!! html
+!! html/php
==b== <!-- -->
!! end
@@ -16401,7 +17377,7 @@ section=1
==a==
==bogus== <nowiki>not a legal section</nowiki>
==b==
-!! html
+!! html/php
==a==
==bogus== <nowiki>not a legal section</nowiki>
!! end
@@ -16414,11 +17390,10 @@ section=2
==a==
==bogus== <nowiki>not a legal section</nowiki>
==b==
-!! html
+!! html/php
==b==
!! end
-
# Formerly testing for bug 2587, now resolved by the use of unmarked sections
# instead of respecting commented sections
!! test
@@ -16428,7 +17403,7 @@ section=1
!! wikitext
<!-- -->==sec1==
==sec2==
-!! html
+!! html/php
==sec2==
!!end
@@ -16439,11 +17414,10 @@ section=2
!! wikitext
<!-- -->==sec1==
==sec2==
-!! html
+!! html/php
!!end
-
# Formerly testing for bug 2607, now resolved by the use of unmarked sections
# instead of respecting HTML-style headings
!! test
@@ -16457,7 +17431,7 @@ unmarked
one
==2==
two
-!! html
+!! html/php
==1==
one
!! end
@@ -16473,7 +17447,7 @@ unmarked
one
==2==
two
-!! html
+!! html/php
==2==
two
!! end
@@ -16487,7 +17461,7 @@ section=1
!! wikitext
<noinclude>==unmarked==</noinclude>
==marked==
-!! html
+!! html/php
==marked==
!!end
@@ -16502,7 +17476,7 @@ The line above must have a trailing space
=== <!--
--> <!-- -->
But just in case it doesn't...
-!! html
+!! html/php
=== <!--
--> <!-- -->
But just in case it doesn't...
@@ -16524,7 +17498,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
xxx
==a==
@@ -16555,7 +17529,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
xxx
@@ -16584,7 +17558,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
xxx
@@ -16614,7 +17588,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16645,7 +17619,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16672,7 +17646,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16703,7 +17677,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16733,7 +17707,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16764,7 +17738,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16795,7 +17769,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16824,7 +17798,7 @@ start
===bc===
==c==
===ca===
-!! html
+!! html/php
start
==a==
===aa===
@@ -16846,7 +17820,7 @@ replace=2,"xxx"
Preformatted initial line
==a==
===a===
-!! html
+!! html/php
Preformatted initial line
==a==
xxx
@@ -16860,7 +17834,7 @@ section=1
!! wikitext
==a==
a
-!! html
+!! html/php
==a==
a
!! end
@@ -16872,7 +17846,7 @@ section=1
!! wikitext
==a==
a
-!! html
+!! html/php
==a==
a
!! end
@@ -16890,7 +17864,7 @@ noxml section=2
== Section Two ==
stuff
-!! html
+!! html/php
== Section Two ==
stuff
!! end
@@ -16907,7 +17881,7 @@ noxml replace=2,"xxx"
== Section Two ==
stuff
-!! html
+!! html/php
== Section One ==
<pre>
=======
@@ -16917,7 +17891,6 @@ xxx
!! end
-
!! test
Handling of &#x0A; in URLs
!! wikitext
@@ -17338,12 +18311,44 @@ parsoid=wt2html,wt2wt,html2html
<p><span typeof="mw:Entity">î</span><span typeof="mw:Entity">î</span></p>
!! end
+# See: http://www.w3.org/TR/html5/syntax.html#character-references
+# Note that U+000C (form feed) is not a valid XML character, so
+# it is banned even though allowed in HTML5.
+!! test
+Illegal character references (T106578)
+!! wikitext
+; Null: &#00;
+; FF: &#xC;
+; CR: &#xD;
+; Control (low): &#8;
+; Control (high): &#x7F; &#x9F;
+; Surrogate: &#xD83D;&#xDCA9;
+; This is an okay astral character: &#x1F4A9;
+!! html+tidy
+<dl>
+<dt>Null</dt>
+<dd>&amp;#00;</dd>
+<dt>FF</dt>
+<dd>&amp;#xC;</dd>
+<dt>CR</dt>
+<dd>&amp;#xD;</dd>
+<dt>Control (low)</dt>
+<dd>&amp;#8;</dd>
+<dt>Control (high)</dt>
+<dd>&amp;#x7F; &amp;#x9F;</dd>
+<dt>Surrogate</dt>
+<dd>&amp;#xD83D;&amp;#xDCA9;</dd>
+<dt>This is an okay astral character</dt>
+<dd>💩</dd>
+</dl>
+!! end
+
!! test
__FORCETOC__ override
!! wikitext
__NEWSECTIONLINK__
__FORCETOC__
-!! html
+!! html/php
<p><br />
</p>
!! end
@@ -17358,7 +18363,7 @@ ISBN 978-0-1234-56&#x20;789
!! html+tidy
<p><a href="/wiki/Special:BookSources/9780123456" class="internal mw-magiclink-isbn">ISBN 978-0-1234-56</a> 789</p>
!! html/parsoid
-<p><a href="./Special:BookSources/9780123456" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 978-0-1234-56</a><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#x20;","srcContent":" "}'> </span>789</p>
+<p><a href="./Special:BookSources/9780123456" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 978-0-1234-56</a><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#x20;","srcContent":" "}'> </span>789</p>
!! end
!! test
@@ -17378,24 +18383,34 @@ ISBN ISBN 1234567890
<p>ISBN <a href="/wiki/Special:BookSources/1234567890" class="internal mw-magiclink-isbn">ISBN 1234567890</a>
</p>
!! html/parsoid
-<p>ISBN <a href="./Special:BookSources/1234567890" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a></p>
+<p>ISBN <a href="./Special:BookSources/1234567890" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a></p>
!! end
+# Uppercase X and lowercase x as well
!! test
ISBN with an X
!! wikitext
ISBN 3-462-04561-X
+ISBN 3-462-04561-x
ISBN 080442957X
+ISBN 080442957x
ISBN 978080442957X
+ISBN 978080442957x
!! html/php
<p><a href="/wiki/Special:BookSources/346204561X" class="internal mw-magiclink-isbn">ISBN 3-462-04561-X</a>
+<a href="/wiki/Special:BookSources/346204561X" class="internal mw-magiclink-isbn">ISBN 3-462-04561-x</a>
<a href="/wiki/Special:BookSources/080442957X" class="internal mw-magiclink-isbn">ISBN 080442957X</a>
+<a href="/wiki/Special:BookSources/080442957X" class="internal mw-magiclink-isbn">ISBN 080442957x</a>
<a href="/wiki/Special:BookSources/978080442957X" class="internal mw-magiclink-isbn">ISBN 978080442957X</a>
+<a href="/wiki/Special:BookSources/978080442957X" class="internal mw-magiclink-isbn">ISBN 978080442957x</a>
</p>
!! html/parsoid
-<p><a href="./Special:BookSources/346204561X" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 3-462-04561-X</a>
-<a href="./Special:BookSources/080442957X" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 080442957X</a>
-<a href="./Special:BookSources/978080442957X" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 978080442957X</a></p>
+<p><a href="./Special:BookSources/346204561X" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 3-462-04561-X</a>
+<a href="./Special:BookSources/346204561X" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 3-462-04561-x</a>
+<a href="./Special:BookSources/080442957X" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 080442957X</a>
+<a href="./Special:BookSources/080442957X" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 080442957x</a>
+<a href="./Special:BookSources/978080442957X" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 978080442957X</a>
+<a href="./Special:BookSources/978080442957X" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 978080442957x</a></p>
!! end
!! test
@@ -17406,7 +18421,7 @@ ISBN 1234567890
<p><a href="/wiki/Special:BookSources/1234567890" class="internal mw-magiclink-isbn">ISBN 1234567890</a>
</p>
!! html/parsoid
-<p><a href="Special:BookSources/1234567890" rel="mw:ExtLink">ISBN 1234567890</a></p>
+<p><a href="./Special:BookSources/1234567890" rel="mw:WikiLink">ISBN 1234567890</a></p>
!! end
!! test
@@ -17417,7 +18432,7 @@ Bug 22905: <abbr> followed by ISBN followed by </a>
<p><abbr>(fr)</abbr> <a href="/wiki/Special:BookSources/2753300917" class="internal mw-magiclink-isbn">ISBN 2753300917</a> <a rel="nofollow" class="external text" href="http://www.example.com">example.com</a>
</p>
!! html/parsoid
-<p><abbr data-parsoid='{"stx":"html"}'>(fr)</abbr> <a href="./Special:BookSources/2753300917" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 2753300917</a> <a rel="mw:ExtLink" href="http://www.example.com">example.com</a></p>
+<p><abbr data-parsoid='{"stx":"html"}'>(fr)</abbr> <a href="./Special:BookSources/2753300917" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 2753300917</a> <a rel="mw:ExtLink" href="http://www.example.com">example.com</a></p>
!! end
!! test
@@ -17548,7 +18563,7 @@ Images with the "|" character in the comment
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>An <a rel="nofollow" class="external text" href="http://test/?param1=%7Cleft%7C&amp;param2=%7Cx">external</a> URL</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>An <a rel="mw:ExtLink" href="http://test/?param1=|left|&amp;param2=|x">external</a> URL</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>An <a rel="mw:ExtLink" href="http://test/?param1=|left|&amp;param2=|x">external</a> URL</figcaption></figure>
!! end
!! test
@@ -17704,7 +18719,7 @@ Don't fall for the self-closing div
MSGNW magic word
!! wikitext
{{MSGNW:msg}}
-!! html
+!! html/php
<p>&#91;&#91;:Template:Msg&#93;&#93;
</p>
!! end
@@ -18294,6 +19309,61 @@ Raw: -{R|zh:China;zh-tw:Taiwan}-
!! end
!! test
+Strings evaluating false shouldn't be ignored by Language converter (T51072)
+!! options
+language=zh variant=zh-cn
+!! input
+-{zh-cn:0;zh-sg:1;zh-tw:2;zh-hk:3}-
+!! result
+<p>0
+</p>
+!! end
+
+!! test
+Conversion rules from [numeric-only string] to [something else] (T48634)
+!! options
+language=zh variant=zh-cn
+!! input
+-{H|0=>zh-cn:B}--{H|0=>zh-cn:C;0=>zh-cn:D}--{H|0=>zh-hans:A}-012345-{A|zh-tw:0;zh-cn:E;}-012345
+!! result
+<p>D12345EE12345
+</p>
+!! end
+
+!! test
+Bidirectional converter rule entries with an empty value should be ignored (T53551)
+!! options
+language=zh variant=zh-cn
+!! input
+-{H|zh-cn:foo;zh-tw:;}-foobar
+!! result
+<p>foobar
+</p>
+!! end
+
+!! test
+Unidirectional converter rule entries with an empty "from" string should be ignored (T53551)
+!! options
+language=zh variant=zh-cn
+!! input
+-{H|=>zh-cn:foo;}-foobar
+!! result
+<p>foobar
+</p>
+!! end
+
+!! test
+Empty converter rule entries shouldn't be inserted into the conversion table (T53551)
+!! options
+language=zh variant=zh-cn
+!! input
+-{H|}-foobar
+!! result
+<p>foobar
+</p>
+!! end
+
+!! test
Nested using of manual convert syntax
!! options
language=zh variant=zh-hk
@@ -19038,7 +20108,7 @@ percent-encoding and + signs in comments (Bug 26410)
comment
!! wikitext
[[ABC%33D% ++]] [[ABC%33D% ++|+%20]]
-!! html
+!! html/php
<a href="/index.php?title=ABC3D%25_%2B%2B&amp;action=edit&amp;redlink=1" class="new" title="ABC3D% ++ (page does not exist)">ABC3D% ++</a> <a href="/index.php?title=ABC3D%25_%2B%2B&amp;action=edit&amp;redlink=1" class="new" title="ABC3D% ++ (page does not exist)">+%20</a>
!! end
@@ -19082,7 +20152,7 @@ wgAllowDisplayTitle=true
wgRestrictDisplayTitle=false
!! wikitext
this is not the the title
-!! html
+!! html/php
Parser test
<p>this is not the the title
</p>
@@ -19099,7 +20169,7 @@ wgRestrictDisplayTitle=false
!! wikitext
this is not the the title
{{DISPLAYTITLE:whatever}}
-!! html
+!! html/php
whatever
<p>this is not the the title
</p>
@@ -19116,7 +20186,7 @@ wgRestrictDisplayTitle=true
!! wikitext
this is not the the title
{{DISPLAYTITLE:whatever}}
-!! html
+!! html/php
Screen
<p>this is not the the title
</p>
@@ -19133,7 +20203,7 @@ wgRestrictDisplayTitle=true
!! wikitext
this is not the the title
{{DISPLAYTITLE:screen}}
-!! html
+!! html/php
screen
<p>this is not the the title
</p>
@@ -19149,7 +20219,7 @@ wgAllowDisplayTitle=false
!! wikitext
this is not the the title
{{DISPLAYTITLE:screen}}
-!! html
+!! html/php
Screen
<p>this is not the the title
<a href="/index.php?title=Template:DISPLAYTITLE:screen&amp;action=edit&amp;redlink=1" class="new" title="Template:DISPLAYTITLE:screen (page does not exist)">Template:DISPLAYTITLE:screen</a>
@@ -19165,7 +20235,7 @@ title=[[Screen]]
wgAllowDisplayTitle=false
!! wikitext
this is not the the title
-!! html
+!! html/php
Screen
<p>this is not the the title
</p>
@@ -19182,7 +20252,7 @@ wgRestrictDisplayTitle=true
!! wikitext
this is not the the title
{{DISPLAYTITLE:<span style="display: none;">s</span>creen}}
-!! html
+!! html/php
<span style="/* attempt to bypass $wgRestrictDisplayTitle */">s</span>creen
<p>this is not the the title
</p>
@@ -19199,7 +20269,7 @@ wgRestrictDisplayTitle=true
!! wikitext
this is not the the title
{{DISPLAYTITLE:<span style="color: red;">s</span>creen}}
-!! html
+!! html/php
<span style="color: red;">s</span>creen
<p>this is not the the title
</p>
@@ -19224,7 +20294,7 @@ Page status indicators: Weird syntaxes that are okay
showindicators
!! wikitext
<indicator name="empty" />
-<indicator name></indicator>
+<indicator name="name"></indicator>
!! html
empty=
name=
@@ -19287,7 +20357,7 @@ preload: check <noinclude> and <includeonly>
preload
!! wikitext
Hello <noinclude>cruel</noinclude><includeonly>kind</includeonly> world.
-!! html
+!! html/php
Hello kind world.
!! end
@@ -19297,7 +20367,7 @@ preload: check <onlyinclude>
preload
!! wikitext
Goodbye <onlyinclude>Hello world</onlyinclude>
-!! html
+!! html/php
Hello world
!! end
@@ -19307,7 +20377,7 @@ preload: can pass tags through if we want to
preload
!! wikitext
<includeonly><</includeonly>includeonly>Hello world<includeonly><</includeonly>/includeonly>
-!! html
+!! html/php
<includeonly>Hello world</includeonly>
!! end
@@ -19317,7 +20387,7 @@ preload: check that it doesn't try to do tricks
preload
!! wikitext
* <!-- Hello --> ''{{world}}'' {{<includeonly>subst:</includeonly>How are you}}{{ {{{|safesubst:}}} #if:1|2|3}}
-!! html
+!! html/php
* <!-- Hello --> ''{{world}}'' {{subst:How are you}}{{ {{{|safesubst:}}} #if:1|2|3}}
!! end
@@ -19368,7 +20438,10 @@ percent-encoding and + signs in internal links (Bug 26410)
<a href="/index.php?title=3E&amp;action=edit&amp;redlink=1" class="new" title="3E (page does not exist)">3E</a> <a href="/index.php?title=3E%2B&amp;action=edit&amp;redlink=1" class="new" title="3E+ (page does not exist)">3E+</a>
</p>
!! html/parsoid
-<p><a rel="mw:WikiLink" href="User:+%" title="User:+%">User:+%</a> <a rel="mw:WikiLink" href="Page+title%" title="Page+title%">Page+title%</a> <a rel="mw:WikiLink" href="%+" title="%+">%+</a> <a rel="mw:WikiLink" href="%+" title="%+">%20</a> <a rel="mw:WikiLink" href="%+" title="%+">%+ </a> <a rel="mw:WikiLink" href="%+r" title="%+r">%+r</a> <a rel="mw:WikiLink" href="%" title="%">%</a> <a rel="mw:WikiLink" href="+" title="+">+</a> <span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"[[bar]]"}'><a href="./File:%+abc9"><img resource="./File:%25+abc9" src="./Special:FilePath/%+abc9" height="220" width="220"/></a></span> <a rel="mw:WikiLink" href="3E" title="3E">3E</a> <a rel="mw:WikiLink" href="3E+" title="3E+">3E+</a></p>
+<p><a rel="mw:WikiLink" href="./User:+%25" title="User:+%">User:+%</a> <a rel="mw:WikiLink" href="Page+title%25" title="Page+title%">Page+title%</a>
+<a rel="mw:WikiLink" href="%25+" title="%+">%+</a> <a rel="mw:WikiLink" href="%25+" title="%+">%20</a> <a rel="mw:WikiLink" href="%25+" title="%+">%+ </a> <a rel="mw:WikiLink" href="%25+r" title="%+r">%+r</a>
+<a rel="mw:WikiLink" href="%25" title="%">%</a> <a rel="mw:WikiLink" href="+" title="+">+</a> <span class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"foo"},{"ck":"caption","ak":"[[bar]]"}]}' data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&lt;a rel=\"mw:WikiLink\" href=\"./Bar\" title=\"Bar\" data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;simple&amp;quot;,&amp;quot;a&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;./Bar&amp;quot;},&amp;quot;sa&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;bar&amp;quot;},&amp;quot;dsr&amp;quot;:[94,101,2,2]}\">bar&lt;/a>"}'><a href="./File:%25+abc9"><img resource="./File:%25+abc9" src="./Special:FilePath/%25+abc9" height="220" width="220" data-parsoid='{"a":{"resource":"./File:%25+abc9","height":"220","width":"220"},"sa":{"resource":"File:%+abc%39"}}'/></a></span>
+<a rel="mw:WikiLink" href="./3E" title="3E" data-parsoid='{"stx":"simple","a":{"href":"./3E"},"sa":{"href":"%33%45"}}'>3E</a> <a rel="mw:WikiLink" href="./3E+" title="3E+" data-parsoid='{"stx":"simple","a":{"href":"./3E+"},"sa":{"href":"%33%45+"}}'>3E+</a></p>
!! end
!! test
@@ -19382,7 +20455,7 @@ Special characters in embedded file links (bug 27679)
</p>
!! html/parsoid
<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}]}'><a href="./File:Contains_&amp;_ampersand.jpg"><img resource="./File:Contains_&amp;_ampersand.jpg" src="./Special:FilePath/Contains_&amp;_ampersand.jpg" height="220" width="220"/></a></span>
-<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"Title with &amp; ampersand"}'><a href="./File:Does_not_exist.jpg"><img resource="./File:Does_not_exist.jpg" src="./Special:FilePath/Does_not_exist.jpg" height="220" width="220"/></a></span></p>
+<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"Title with &amp;amp; ampersand"}'><a href="./File:Does_not_exist.jpg"><img resource="./File:Does_not_exist.jpg" src="./Special:FilePath/Does_not_exist.jpg" height="220" width="220"/></a></span></p>
!! end
!! test
@@ -19653,14 +20726,18 @@ __TOC__
<p><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></p>
!! end
+# Don't expect Parsoid to roundtrip this until the php parser comes closer to
+# html5 tag parsing.
!! test
Tags with parameters in TOC
+!! options
+parsoid=wt2html
!! wikitext
__TOC__
== <sup class="in-h2">Hello</sup> ==
== <sup class="a > b">Evilbye</sup> ==
-!! html
+!! html/php
<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
<ul>
<li class="toclevel-1 tocsection-1"><a href="#Hello"><span class="tocnumber">1</span> <span class="toctext"><sup>Hello</sup></span></a></li>
@@ -19669,8 +20746,13 @@ __TOC__
</div>
<h2><span class="mw-headline" id="Hello"><sup class="in-h2">Hello</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Hello">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-<h2><span class="mw-headline" id="b.22.3EEvilbye"><sup> b"&gt;Evilbye</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: b&quot;&gt;Evilbye">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="b.22.3EEvilbye"><sup class="a"> b"&gt;Evilbye</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: b&quot;&gt;Evilbye">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! html/parsoid
+<meta property="mw:PageProp/toc" />
+<h2> <sup class="in-h2" data-parsoid='{"stx":"html"}'>Hello</sup> </h2>
+
+<h2> <sup class="a " data-parsoid='{"stx":"html"}'> b">Evilbye</sup> </h2>
!! end
!! test
@@ -19775,10 +20857,12 @@ Strip marker in urlencode
{{urlencode:x<nowiki/>y}}
{{urlencode:x<nowiki/>y|wiki}}
{{urlencode:x<nowiki/>y|path}}
+{{urlencode:x<pre id="one">two</pre>y}}
!! html
<p>xy
xy
xy
+xy
</p>
!! end
@@ -20137,10 +21221,35 @@ parsoid=wt2html,wt2wt
<small>[[Image:Foobar.jpg|right|300px]]</small>
!! html/parsoid
+
<p><b>foo</b></p>
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><b>caption</b></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><b>caption</b></figcaption></figure>
<p><b>bar</b></p>
-<small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small>
+<small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small>
+!! end
+
+!! test
+3. Bad treebuilder fixup of formatting elt is cleaned up
+!! options
+parsoid=wt2html,wt2wt
+!! wikitext
+<small>'''foo[[File:Foobar.jpg|thumb|caption]]bar'''</small>
+!! html/parsoid
+<p><small><b>foo</b></small></p>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><small><b>caption</b></small></figcaption></figure>
+<p><small><b>bar</b></small></p>
+!! end
+
+!! test
+4. Bad treebuilder fixup of formatting elt is cleaned up: formatting tags around captionless images are ignored
+!! options
+parsoid=wt2html,wt2wt
+!! wikitext
+'''<small>[[Image:Foobar.jpg|right|300px]]</small>'''
+!! html/parsoid
+<p><b><small></small></b></p>
+<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure>
+<p></p>
!! end
#### ----------------------------------------------------------------
@@ -20159,13 +21268,13 @@ B <ref name="x">foo</ref>
C <ref name="y" />
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-x_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-x-2"},"attrs":{"name":"x"}}'><a href="#cite_note-x-2">[2]</a></span>
-C <span about="#mwt6" class="reference" id="cite_ref-y_3-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"y"}}'><a href="#cite_note-y-3">[3]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
-<li about="#cite_note-x-2" id="cite_note-x-2"><span rel="mw:referencedBy"><a href="#cite_ref-x_2-0">↑</a></span> <span id="mw-reference-text-cite_note-x-2" class="mw-reference-text">foo</span></li>
-<li about="#cite_note-y-3" id="cite_note-y-3"><span rel="mw:referencedBy"><a href="#cite_ref-y_3-0">↑</a></span> <span id="mw-reference-text-cite_note-y-3" class="mw-reference-text"></span></li>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-x_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-x-2"},"attrs":{"name":"x"}}'><a href="#cite_note-x-2"><span class="mw-reflink-text">[2]</span></a></span>
+C <span about="#mwt6" class="mw-ref" id="cite_ref-y_3-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"y"}}'><a href="#cite_note-y-3"><span class="mw-reflink-text">[3]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
+<li about="#cite_note-x-2" id="cite_note-x-2"><a href="#cite_ref-x_2-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-x-2" class="mw-reference-text">foo</span></li>
+<li about="#cite_note-y-3" id="cite_note-y-3"><a href="#cite_ref-y_3-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-y-3" class="mw-reference-text"></span></li>
</ol>
!!end
@@ -20178,10 +21287,10 @@ A <ref name="x">foo</ref>
B <ref name="x" />
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-x_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-x-1"},"attrs":{"name":"x"}}'><a href="#cite_note-x-1">[1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-x_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"x"}}'><a href="#cite_note-x-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-x-1" id="cite_note-x-1"><span rel="mw:referencedBy">↑ <a href="#cite_ref-x_1-0">1.0</a> <a href="#cite_ref-x_1-1">1.1</a></span> <span id="mw-reference-text-cite_note-x-1" class="mw-reference-text">foo</span></li>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-x_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-x-1"},"attrs":{"name":"x"}}'><a href="#cite_note-x-1"><span class="mw-reflink-text">[1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-x_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"x"}}'><a href="#cite_note-x-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-x-1" id="cite_note-x-1"><span rel="mw:referencedBy"><a href="#cite_ref-x_1-0"><span class="mw-linkback-text">1 </span></a><a href="#cite_ref-x_1-1"><span class="mw-linkback-text">2 </span></a></span> <span id="mw-reference-text-cite_note-x-1" class="mw-reference-text">foo</span></li>
</ol>
!!end
@@ -20195,11 +21304,11 @@ B <ref name=" x " />
C <ref name= x />
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-x_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-x-1"},"attrs":{"name":"x"}}'><a href="#cite_note-x-1">[1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-x_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"x"}}'><a href="#cite_note-x-1">[1]</a></span>
-C <span about="#mwt6" class="reference" id="cite_ref-x_1-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"x"}}'><a href="#cite_note-x-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-x-1" id="cite_note-x-1"><span rel="mw:referencedBy">↑ <a href="#cite_ref-x_1-0">1.0</a> <a href="#cite_ref-x_1-1">1.1</a> <a href="#cite_ref-x_1-2">1.2</a></span> <span id="mw-reference-text-cite_note-x-1" class="mw-reference-text">foo</span></li>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-x_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-x-1"},"attrs":{"name":"x"}}'><a href="#cite_note-x-1"><span class="mw-reflink-text">[1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-x_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"x"}}'><a href="#cite_note-x-1"><span class="mw-reflink-text">[1]</span></a></span>
+C <span about="#mwt6" class="mw-ref" id="cite_ref-x_1-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"x"}}'><a href="#cite_note-x-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-x-1" id="cite_note-x-1"><span rel="mw:referencedBy"><a href="#cite_ref-x_1-0"><span class="mw-linkback-text">1 </span></a><a href="#cite_ref-x_1-1"><span class="mw-linkback-text">2 </span></a><a href="#cite_ref-x_1-2"><span class="mw-linkback-text">3 </span></a></span> <span id="mw-reference-text-cite_note-x-1" class="mw-reference-text">foo</span></li>
</ol>
!!end
@@ -20212,9 +21321,9 @@ parsoid
A <ref name="constructor">foo</ref>
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-constructor_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-constructor-1"},"attrs":{"name":"constructor"}}'><a href="#cite_note-constructor-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-constructor-1" id="cite_note-constructor-1"><span rel="mw:referencedBy"><a href="#cite_ref-constructor_1-0">↑</a></span> <span id="mw-reference-text-cite_note-constructor-1" class="mw-reference-text">foo</span></li>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-constructor_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-constructor-1"},"attrs":{"name":"constructor"}}'><a href="#cite_note-constructor-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-constructor-1" id="cite_note-constructor-1"><a href="#cite_ref-constructor_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-constructor-1" class="mw-reference-text">foo</span></li>
</ol>
!!end
@@ -20229,10 +21338,10 @@ A <ref>
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">This is a <b><a rel="mw:WikiLink" href="Bolded_link" title="Bolded link">bolded link</a></b> and this is a <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">This is a <b><a rel="mw:WikiLink" href="Bolded_link" title="Bolded link">bolded link</a></b> and this is a <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span>
</span></li>
</ol>
!!end
@@ -20250,10 +21359,10 @@ A <ref>
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo
bar
baz
</span></li>
@@ -20280,10 +21389,10 @@ booz
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo
bar
@@ -20306,9 +21415,9 @@ A <ref> foo {{echo|</ref> B C}}
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span> B C<span typeof="mw:Nowiki">}}</span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo <span typeof="mw:Nowiki" data-parsoid='{"src":"{{","dsr":[12,14,0,0]}'>{{</span>echo|</span></li>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> B C<span typeof="mw:Nowiki">}}</span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo <span typeof="mw:Nowiki" data-parsoid='{"src":"{{","dsr":[12,14,0,0]}'>{{</span>echo|</span></li>
</ol>
!!end
@@ -20320,9 +21429,9 @@ parsoid
A <ref> foo <!--</ref> B C
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span> B C</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo <!----></span></li>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> B C</p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo <!----></span></li>
</ol>
!!end
@@ -20335,11 +21444,11 @@ A <ref> <b> foo </ref> B C
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span> B C</p>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> B C</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><b data-parsoid='{"stx":"html","autoInsertedEnd":true}'> foo </b></span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><b data-parsoid='{"stx":"html","autoInsertedEnd":true}'> foo </b></span></li>
</ol>
!!end
@@ -20352,37 +21461,35 @@ A <ref>foo</ref> B
C <ref>bar</ref> D
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span> B
-C <span about="#mwt4" class="reference" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2">[2]</a></span> D</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
-<li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2">↑</a></span> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> B
+C <span about="#mwt4" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2"><span class="mw-reflink-text">[2]</span></a></span> D</p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
+<li about="#cite_note-2" id="cite_note-2"><a href="#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
</ol>
!!end
!!test
Ref: 12. ref-tags act as trailing newline migration barrier
-!!options
-parsoid
!! wikitext
-<!--the newline at the end of this line moves out of the p-tag-->a
+<!--the newline at the end of this line moves out of the p tag-->a
-b<!--the newline at the end of this line stays inside the p-tag--> <ref />
+b<!--the newline at the end of this line stays inside the p tag--> <ref />
<ref />
c
<references />
-!! html
-<p><!--the newline at the end of this line moves out of the p-tag-->a</p>
+!! html/parsoid
+<!--the newline at the end of this line moves out of the p tag--><p>a</p>
-<p>b<!--the newline at the end of this line stays inside the p-tag--> <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{}}'><a href="#cite_note-1">[1]</a></span>
-<span about="#mwt4" class="reference" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{}}'><a href="#cite_note-2">[2]</a></span></p>
+<p>b<!--the newline at the end of this line stays inside the p tag--> <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span>
+<span about="#mwt4" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{}}'><a href="#cite_note-2"><span class="mw-reflink-text">[2]</span></a></span></p>
<p>c</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"></span></li>
-<li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2">↑</a></span> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"></span></li></ol>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"></span></li>
+<li about="#cite_note-2" id="cite_note-2"><a href="#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"></span></li></ol>
!!end
!!test
@@ -20395,11 +21502,11 @@ parsoid
</ref> B
<references />
!! html
-<p><span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span> A
-<span about="#mwt4" class="reference" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2">[2]</a></span> B</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
-<li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2">↑</a></span> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar
+<p><span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> A
+<span about="#mwt4" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2"><span class="mw-reflink-text">[2]</span></a></span> B</p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
+<li about="#cite_note-2" id="cite_note-2"><a href="#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar
</span></li>
</ol>
!!end
@@ -20413,10 +21520,10 @@ parsoid
<references />
!! html
-<p><span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span>
+<p><span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span>
</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo &lt;ref>bar&lt;/ref> baz</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo &lt;ref>bar&lt;/ref> baz</span></li>
</ol>
!!end
@@ -20430,10 +21537,10 @@ B1 <ref name="b" /> B2 <ref name="b">bar</ref>
<references />
!! html
-<p>A1 <span about="#mwt3" class="reference" id="cite_ref-a_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-a-1"},"attrs":{"name":"a"}}'><a href="#cite_note-a-1">[1]</a></span> A2 <span about="#mwt4" class="reference" id="cite_ref-a_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"a"}}'><a href="#cite_note-a-1">[1]</a></span>
-B1 <span about="#mwt7" class="reference" id="cite_ref-b_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"b"}}'><a href="#cite_note-b-2">[2]</a></span> B2 <span about="#mwt8" class="reference" id="cite_ref-b_2-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-b-2"},"attrs":{"name":"b"}}'><a href="#cite_note-b-2">[2]</a></span></p>
+<p>A1 <span about="#mwt3" class="mw-ref" id="cite_ref-a_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-a-1"},"attrs":{"name":"a"}}'><a href="#cite_note-a-1"><span class="mw-reflink-text">[1]</span></a></span> A2 <span about="#mwt4" class="mw-ref" id="cite_ref-a_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"a"}}'><a href="#cite_note-a-1"><span class="mw-reflink-text">[1]</span></a></span>
+B1 <span about="#mwt7" class="mw-ref" id="cite_ref-b_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"b"}}'><a href="#cite_note-b-2"><span class="mw-reflink-text">[2]</span></a></span> B2 <span about="#mwt8" class="mw-ref" id="cite_ref-b_2-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-b-2"},"attrs":{"name":"b"}}'><a href="#cite_note-b-2"><span class="mw-reflink-text">[2]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt10" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><span rel="mw:referencedBy">↑ <a href="#cite_ref-a_1-0">1.0</a> <a href="#cite_ref-a_1-1">1.1</a></span> <span id="mw-reference-text-cite_note-a-1" class="mw-reference-text">foo</span></li><li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy">↑ <a href="#cite_ref-b_2-0">2.0</a> <a href="#cite_ref-b_2-1">2.1</a></span> <span id="mw-reference-text-cite_note-b-2" class="mw-reference-text">bar</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt10" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><span rel="mw:referencedBy"><a href="#cite_ref-a_1-0"><span class="mw-linkback-text">1 </span></a><a href="#cite_ref-a_1-1"><span class="mw-linkback-text">2 </span></a></span> <span id="mw-reference-text-cite_note-a-1" class="mw-reference-text">foo</span></li><li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy"><a href="#cite_ref-b_2-0"><span class="mw-linkback-text">1 </span></a><a href="#cite_ref-b_2-1"><span class="mw-linkback-text">2 </span></a></span> <span id="mw-reference-text-cite_note-b-2" class="mw-reference-text">bar</span></li>
</ol>
!!end
@@ -20447,9 +21554,9 @@ A <ref >foo</ref >
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
!!end
!!test
@@ -20461,11 +21568,11 @@ parsoid
<references />
!!html
-<p><span class="reference" id="cite_ref-a_b_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-a_b-1"},"attrs":{"name":"a b"}}'><a href="#cite_note-a_b-1">[1]</a></span>
+<p><span class="mw-ref" id="cite_ref-a_b_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-a_b-1"},"attrs":{"name":"a b"}}'><a href="#cite_note-a_b-1"><span class="mw-reflink-text">[1]</span></a></span>
</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-a_b-1" id="cite_note-a_b-1"><span rel="mw:referencedBy"><a href="#cite_ref-a_b_1-0">↑</a></span> <span id="mw-reference-text-cite_note-a_b-1" class="mw-reference-text">foo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-a_b-1" id="cite_note-a_b-1"><a href="#cite_ref-a_b_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-a_b-1" class="mw-reference-text">foo</span></li>
</ol>
!!end
@@ -20478,11 +21585,11 @@ parsoid
<references />
!!html
-<p><span class="reference" id="cite_ref-.7B.7Becho.7Ca.7D.7D_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-.7B.7Becho.7Ca.7D.7D-1"},"attrs":{"name":"{{echo|a}}"}}'><a href="#cite_note-.7B.7Becho.7Ca.7D.7D-1">[1]</a></span>
+<p><span class="mw-ref" id="cite_ref-.7B.7Becho.7Ca.7D.7D_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-.7B.7Becho.7Ca.7D.7D-1"},"attrs":{"name":"{{echo|a}}"}}'><a href="#cite_note-.7B.7Becho.7Ca.7D.7D-1"><span class="mw-reflink-text">[1]</span></a></span>
</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-.7B.7Becho.7Ca.7D.7D-1" id="cite_note-.7B.7Becho.7Ca.7D.7D-1"><span rel="mw:referencedBy"><a href="#cite_ref-.7B.7Becho.7Ca.7D.7D_1-0">↑</a></span> <span id="mw-reference-text-cite_note-.7B.7Becho.7Ca.7D.7D-1" class="mw-reference-text">foo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-.7B.7Becho.7Ca.7D.7D-1" id="cite_note-.7B.7Becho.7Ca.7D.7D-1"><a href="#cite_ref-.7B.7Becho.7Ca.7D.7D_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-.7B.7Becho.7Ca.7D.7D-1" class="mw-reference-text">foo</span></li>
</ol>
!!end
@@ -20495,10 +21602,10 @@ parsoid
<references />
!! html
-<p>1 <span about="#mwt3" class="reference" id="cite_ref-a_.26_b_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-a_.26_b-1"},"attrs":{"name":"a &amp; b"}}'><a href="#cite_note-a_.26_b-1">[1]</a></span> 2 <span about="#mwt4" class="reference" id="cite_ref-a_.26_b_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"a &amp;amp; b"}}'><a href="#cite_note-a_.26_b-1">[1]</a></span>
+<p>1 <span about="#mwt3" class="mw-ref" id="cite_ref-a_.26_b_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-a_.26_b-1"},"attrs":{"name":"a &amp; b"}}'><a href="#cite_note-a_.26_b-1"><span class="mw-reflink-text">[1]</span></a></span> 2 <span about="#mwt4" class="mw-ref" id="cite_ref-a_.26_b_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"a &amp;amp; b"}}'><a href="#cite_note-a_.26_b-1"><span class="mw-reflink-text">[1]</span></a></span>
</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-a_.26_b-1" id="cite_note-a_.26_b-1"><span rel="mw:referencedBy">↑ <a href="#cite_ref-a_.26_b_1-0">1.0</a> <a href="#cite_ref-a_.26_b_1-1">1.1</a></span> <span id="mw-reference-text-cite_note-a_.26_b-1" class="mw-reference-text">foo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-a_.26_b-1" id="cite_note-a_.26_b-1"><span rel="mw:referencedBy"><a href="#cite_ref-a_.26_b_1-0"><span class="mw-linkback-text">1 </span></a><a href="#cite_ref-a_.26_b_1-1"><span class="mw-linkback-text">2 </span></a></span> <span id="mw-reference-text-cite_note-a_.26_b-1" class="mw-reference-text">foo</span></li>
</ol>
!!end
@@ -20513,28 +21620,24 @@ C <ref name="foo" />
<references />
!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-foo_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-foo-1"},"attrs":{"name":"foo"}}'><a href="#cite_note-foo-1">[1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-foo_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"html":"Foo two"},"attrs":{"name":"foo"}}'><a href="#cite_note-foo-1">[1]</a></span>
-C <span about="#mwt6" class="reference" id="cite_ref-foo_1-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"foo"}}'><a href="#cite_note-foo-1">[1]</a></span></p>
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-foo_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-foo-1"},"attrs":{"name":"foo"}}'><a href="#cite_note-foo-1"><span class="mw-reflink-text">[1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-foo_1-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"html":"Foo two"},"attrs":{"name":"foo"}}'><a href="#cite_note-foo-1"><span class="mw-reflink-text">[1]</span></a></span>
+C <span about="#mwt6" class="mw-ref" id="cite_ref-foo_1-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"foo"}}'><a href="#cite_note-foo-1"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-foo-1" id="cite_note-foo-1"><span rel="mw:referencedBy">↑ <a href="#cite_ref-foo_1-0">1.0</a> <a href="#cite_ref-foo_1-1">1.1</a> <a href="#cite_ref-foo_1-2">1.2</a></span> <span id="mw-reference-text-cite_note-foo-1" class="mw-reference-text">Foo one</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-foo-1" id="cite_note-foo-1"><span rel="mw:referencedBy"><a href="#cite_ref-foo_1-0"><span class="mw-linkback-text">1 </span></a><a href="#cite_ref-foo_1-1"><span class="mw-linkback-text">2 </span></a><a href="#cite_ref-foo_1-2"><span class="mw-linkback-text">3 </span></a></span> <span id="mw-reference-text-cite_note-foo-1" class="mw-reference-text">Foo one</span></li>
</ol>
!!end
!!test
References: 1. references tag without any refs should be handled properly
-!!options
-parsoid
!! wikitext
<references />
-!! html
-<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'></ol>
+!! html/parsoid
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'></ol>
!!end
!!test
References: 2. references tag with group only outputs references from that group
-!!options
-parsoid
!! wikitext
A <ref group="a">foo</ref>
B <ref group="b">bar</ref>
@@ -20543,26 +21646,24 @@ C <ref>baz</ref>
<references group="a" />
<references />
<references group="b" />
-!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{"group":"a"}}'><a href="#cite_note-1">[a 1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{"group":"b"}}'><a href="#cite_note-2">[b 1]</a></span>
-C <span class="reference" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-3"},"attrs":{}}'><a href="#cite_note-3">[1]</a></span></p>
+!! html/parsoid
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{"group":"a"}}'><a href="#cite_note-1" data-mw-group="a"><span class="mw-reflink-text">[a 1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{"group":"b"}}'><a href="#cite_note-2" data-mw-group="b"><span class="mw-reflink-text">[b 1]</span></a></span>
+C <span class="mw-ref" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-3"},"attrs":{}}'><a href="#cite_note-3"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{"group":"a"}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt8" data-mw-group="a" data-mw='{"name":"references","attrs":{"group":"a"}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" data-mw-group="a" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
</ol>
-<ol class="references" typeof="mw:Extension/references" about="#mwt10" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-3" id="cite_note-3"><span rel="mw:referencedBy"><a href="#cite_ref-3">↑</a></span> <span id="mw-reference-text-cite_note-3" class="mw-reference-text">baz</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt10" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-3" id="cite_note-3"><a href="#cite_ref-3" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-3" class="mw-reference-text">baz</span></li>
</ol>
-<ol class="references" typeof="mw:Extension/references" about="#mwt12" data-mw='{"name":"references","attrs":{"group":"b"}}'>
-<li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2">↑</a></span> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt12" data-mw-group="b" data-mw='{"name":"references","attrs":{"group":"b"}}'>
+<li about="#cite_note-2" id="cite_note-2"><a href="#cite_ref-2" data-mw-group="b" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
</ol>
!!end
!!test
References: 3. ref list should be cleared after processing references
-!!options
-parsoid
!! wikitext
A <ref>foo</ref>
@@ -20571,23 +21672,21 @@ A <ref>foo</ref>
B <ref>bar</ref>
<references />
-!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p>
+!! html/parsoid
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
</ol>
-<p>B <span about="#mwt6" class="reference" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2">[1]</a></span></p>
+<p>B <span about="#mwt6" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2">↑</a></span> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-2" id="cite_note-2"><a href="#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
</ol>
!!end
!!test
References: 4. only referenced group should be cleared after processing references
-!!options
-parsoid
!! wikitext
A <ref group="a">afoo</ref>
B <ref>bfoo</ref>
@@ -20597,23 +21696,21 @@ B <ref>bfoo</ref>
C <ref>cfoo</ref>
<references />
-!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{"group":"a"}}'><a href="#cite_note-1">[a 1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2">[1]</a></span></p>
+!! html/parsoid
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{"group":"a"}}'><a href="#cite_note-1" data-mw-group="a"><span class="mw-reflink-text">[a 1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="#cite_note-2"><span class="mw-reflink-text">[1]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">afoo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw-group="a" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" data-mw-group="a" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">afoo</span></li>
</ol>
-<p>C <span about="#mwt8" class="reference" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-3"},"attrs":{}}'><a href="#cite_note-3">[2]</a></span></p>
+<p>C <span about="#mwt8" class="mw-ref" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-3"},"attrs":{}}'><a href="#cite_note-3"><span class="mw-reflink-text">[2]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt10" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2">↑</a></span> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bfoo</span></li><li about="#cite_note-3" id="cite_note-3"><span rel="mw:referencedBy"><a href="#cite_ref-3">↑</a></span> <span id="mw-reference-text-cite_note-3" class="mw-reference-text">cfoo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt10" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-2" id="cite_note-2"><a href="#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bfoo</span></li><li about="#cite_note-3" id="cite_note-3"><a href="#cite_ref-3" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-3" class="mw-reference-text">cfoo</span></li>
</ol>
!!end
!!test
References: 5. ref tags in references should be processed while ignoring all other content
-!!options
-parsoid
!! wikitext
A <ref name="a" />
B <ref name="b">bar</ref>
@@ -20622,30 +21719,26 @@ B <ref name="b">bar</ref>
<ref name="a">foo</ref>
This should just get lost.
</references>
-!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-a_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"a"}}'><a href="#cite_note-a-1">[1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-b_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-b-2"},"attrs":{"name":"b"}}'><a href="#cite_note-b-2">[2]</a></span></p>
+!! html/parsoid
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-a_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"name":"a"}}'><a href="#cite_note-a-1"><span class="mw-reflink-text">[1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-b_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-b-2"},"attrs":{"name":"b"}}'><a href="#cite_note-b-2"><span class="mw-reflink-text">[2]</span></a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"a\">foo&lt;/ref>\nThis should just get lost.","html":"\n&lt;span about=\"#mwt8\" class=\"reference\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[59,82,14,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"body\":{\"id\":\"mw-reference-text-cite_note-a-1\"},\"attrs\":{\"name\":\"a\"}}&#39;>&lt;a href=\"#cite_note-a-1\">[1]&lt;/a>&lt;/span>\n"},"attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><span rel="mw:referencedBy"><a href="#cite_ref-a_1-0">↑</a></span> <span id="mw-reference-text-cite_note-a-1" class="mw-reference-text">foo</span></li><li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy"><a href="#cite_ref-b_2-0">↑</a></span> <span id="mw-reference-text-cite_note-b-2" class="mw-reference-text">bar</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"a\">foo&lt;/ref>\nThis should just get lost.","html":"\n&lt;span about=\"#mwt8\" class=\"mw-ref\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[59,82,14,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"body\":{\"id\":\"mw-reference-text-cite_note-a-1\"},\"attrs\":{\"name\":\"a\"}}&#39;>&lt;a href=\"#cite_note-a-1\" style=\"counter-reset: mw-Ref 1;\">&lt;span class=\"mw-reflink-text\">[1]&lt;/span>&lt;/a>&lt;/span>\n"},"attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><a href="#cite_ref-a_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-a-1" class="mw-reference-text">foo</span></li><li about="#cite_note-b-2" id="cite_note-b-2"><a href="#cite_ref-b_2-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-b-2" class="mw-reference-text">bar</span></li>
</ol>
!!end
!!test
References: 6. <references /> from a transclusion
-!!options
-parsoid
!! wikitext
<ref>Foo</ref> {{echo|<references />}}
-!! html
-<p><span about="#mwt3" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p> <ol class="references" typeof="mw:Extension/references mw:Transclusion" about="#mwt4" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;references />"}},"i":0}}]}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">Foo</span></li>
+!! html/parsoid
+<p><span about="#mwt3" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p> <ol class="mw-references" typeof="mw:Extension/references mw:Transclusion" about="#mwt4" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;references />"}},"i":0}}]}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">Foo</span></li>
</ol>
!!end
!! test
References: 7. Multiple references tags (one without and one with nested refs) should be correctly handled
-!! options
-parsoid
!! wikitext
A <ref>foo bar for a</ref>
B <ref group="X" name="b" />
@@ -20655,30 +21748,28 @@ B <ref group="X" name="b" />
<references group="X">
<ref name="b">foo</ref>
</references>
-!! html
-<p>A <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span>
-B <span about="#mwt4" class="reference" id="cite_ref-b_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"group":"X","name":"b"}}'><a href="#cite_note-b-2">[X 1]</a></span>
+!! html/parsoid
+<p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span>
+B <span about="#mwt4" class="mw-ref" id="cite_ref-b_2-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{"group":"X","name":"b"}}'><a href="#cite_note-b-2" data-mw-group="X"><span class="mw-reflink-text">[X 1]</span></a></span>
</p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo bar for a</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo bar for a</span></li>
</ol>
-<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"b\">foo&lt;/ref>","html":"\n&lt;span about=\"#mwt10\" class=\"reference\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[96,119,14,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"body\":{\"id\":\"mw-reference-text-cite_note-b-2\"},\"attrs\":{\"name\":\"b\"}}&#39;>&lt;a href=\"#cite_note-b-2\">[X 1]&lt;/a>&lt;/span>\n"},"attrs":{"group":"X"}}'>
-<li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy"><a href="#cite_ref-b_2-0">↑</a></span> <span id="mw-reference-text-cite_note-b-2" class="mw-reference-text">foo</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt8" data-mw-group="X" data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"b\">foo&lt;/ref>","html":"\n&lt;span about=\"#mwt10\" class=\"mw-ref\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[96,119,14,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"body\":{\"id\":\"mw-reference-text-cite_note-b-2\"},\"attrs\":{\"name\":\"b\"}}&#39;>&lt;a href=\"#cite_note-b-2\" style=\"counter-reset: mw-Ref 1;\" data-mw-group=\"X\">&lt;span class=\"mw-reflink-text\">[X 1]&lt;/span>&lt;/a>&lt;/span>\n"},"attrs":{"group":"X"}}'>
+<li about="#cite_note-b-2" id="cite_note-b-2"><a href="#cite_ref-b_2-0" data-mw-group="X" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-b-2" class="mw-reference-text">foo</span></li>
</ol>
!! end
!! test
References: 8. T88019: Remove <meta>s from templates inside <ref> that's itself inside a template
-!! options
-parsoid
!! wikitext
X{{echo|<ref>foo {{echo|<b>bar</b>}} and {{echo|baz}} boo</ref>}}
<references />
-!! html
-<p>X<span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo {{echo|&lt;b>bar&lt;/b>}} and {{echo|baz}} boo&lt;/ref>"}},"i":0}}]}'><a href="#cite_note-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt7" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo <b data-parsoid='{"stx":"html"}'>bar</b> and baz boo</span></li>
+!! html/parsoid
+<p>X<span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo {{echo|&lt;b>bar&lt;/b>}} and {{echo|baz}} boo&lt;/ref>"}},"i":0}}]}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt7" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo <b data-parsoid='{"stx":"html"}'>bar</b> and baz boo</span></li>
</ol>
!!end
@@ -20688,18 +21779,16 @@ X{{echo|<ref>foo {{echo|<b>bar</b>}} and {{echo|baz}} boo</ref>}}
# wt2wt.
!! test
References: 9. Generate missing references list at the end
-!! options
-parsoid
!! wikitext
A <ref>foo</ref>
B <ref group="inexistent">bar</ref>
-!! html
-<p>A <span class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span> B <span class="reference" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{"group":"inexistent"}}'><a href="#cite_note-2">[inexistent 1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
+!! html/parsoid
+<p>A <span class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> B <span class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{"group":"inexistent"}}'><a href="#cite_note-2" data-mw-group="inexistent"><span class="mw-reflink-text">[inexistent 1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li>
</ol>
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{"group":"inexistent"}}'>
-<li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2">↑</a></span> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt6" data-mw-group="inexistent" data-mw='{"name":"references","attrs":{"group":"inexistent"}}'>
+<li about="#cite_note-2" id="cite_note-2"><a href="#cite_ref-2" data-mw-group="inexistent" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">bar</span></li>
</ol>
!! end
@@ -20721,15 +21810,13 @@ A <ref>foo</ref>
!! test
Entities in ref name
-!! options
-parsoid
!! wikitext
<ref name="test &amp; me">hi</ref>
<references />
-!! html
-<p><span about="#mwt2" class="reference" id="cite_ref-test_.26_me_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-test_.26_me-1"},"attrs":{"name":"test &amp;amp; me"}}'><a href="#cite_note-test_.26_me-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-test_.26_me-1" id="cite_note-test_.26_me-1"><span rel="mw:referencedBy"><a href="#cite_ref-test_.26_me_1-0">↑</a></span> <span id="mw-reference-text-cite_note-test_.26_me-1" class="mw-reference-text">hi</span></li>
+!! html/parsoid
+<p><span about="#mwt2" class="mw-ref" id="cite_ref-test_.26_me_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-test_.26_me-1"},"attrs":{"name":"test &amp;amp; me"}}'><a href="#cite_note-test_.26_me-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-test_.26_me-1" id="cite_note-test_.26_me-1"><a href="#cite_ref-test_.26_me_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-test_.26_me-1" class="mw-reference-text">hi</span></li>
</ol>
!! end
@@ -20743,10 +21830,10 @@ parsoid=wt2html
a<ref>foo</ref>
<references>
-!! html
-<p>a<span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+!! html/parsoid
+<p>a<span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
!! end
!! test
@@ -20756,8 +21843,8 @@ parsoid=wt2wt,html2wt
!! wikitext
foo
<references />
-!! html
-foo<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'></ol>
+!! html/parsoid
+foo<ol class="mw-references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'></ol>
!! end
#### ----------------------------------------------------------------
@@ -20864,23 +21951,23 @@ Empty TR nodes should not be stripped if they have any attributes set
!! test
Headings: 0. Unnested
!! options
-parsoid
+parsoid=html2wt
+!! html/parsoid
+<p>=foo=</p>
+
+<p> =foo=
+<!--cmt-->
+=foo=</p>
+
+<p>=foo<i>a</i>=</p>
!! wikitext
<nowiki>=foo=</nowiki>
-<nowiki> =foo= </nowiki>
+<nowiki> </nowiki>=foo=
<!--cmt-->
<nowiki>=foo=</nowiki>
=foo''a''<nowiki>=</nowiki>
-!! html
-<p><span typeof="mw:Nowiki">=foo=</span></p>
-
-<p><span typeof="mw:Nowiki"> =foo= </span>
-<!--cmt-->
-<span typeof="mw:Nowiki">=foo=</span></p>
-
-<p>=foo<i>a</i><span typeof="mw:Nowiki">=</span></p>
!!end
# New headings and existing headings are handled differently
@@ -20888,7 +21975,7 @@ parsoid
Headings: 1. Nested inside html
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<h1>=foo=</h1>
<h2>=foo=</h2>
<h3>=foo=</h3>
@@ -20919,7 +22006,7 @@ parsoid=html2wt
Headings: 2. Outside heading nest on a single line <h1>foo</h1>*bar
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<h1>foo</h1>*bar
<h1>foo</h1>=bar
<h1>foo</h1>=bar=
@@ -20937,15 +22024,26 @@ parsoid=html2wt
!! test
Headings: 3. Nested inside html with wikitext split by html tags
!! options
-parsoid=html2wt,wt2wt
-!! wikitext
-= ='''bold'''<nowiki>foo=</nowiki> =
+parsoid=html2wt
!! html/parsoid
<h1>=<b>bold</b>foo=</h1>
+!! wikitext
+= ='''bold'''<nowiki>foo=</nowiki> =
!!end
!! test
Headings: 4a. No escaping needed (testing just h1 and h2)
+!! options
+parsoid=html2wt
+!! html/parsoid
+<h1>=foo</h1>
+<h1>foo=</h1>
+<h1> =foo= </h1>
+<h1>=foo= bar</h1>
+<h2>=foo</h2>
+<h2>foo=</h2>
+<h1>=</h1>
+<h1><i>=</i>foo=</h1>
!! wikitext
= =foo =
@@ -20962,22 +22060,13 @@ Headings: 4a. No escaping needed (testing just h1 and h2)
= = =
= ''=''foo= =
-!! html/parsoid
-<h1>=foo</h1>
-<h1>foo=</h1>
-<h1> =foo= </h1>
-<h1>=foo= bar</h1>
-<h2>=foo</h2>
-<h2>foo=</h2>
-<h1>=</h1>
-<h1><i>=</i>foo=</h1>
!!end
!! test
Headings: 4b. No escaping needed (inside p-tags)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p>===
=foo= x
=foo= <s></s>
@@ -20991,7 +22080,19 @@ parsoid=html2wt
!! test
Headings: 5. Empty headings
!! options
-parsoid
+parsoid=html2wt
+!! html/parsoid
+<h1 data-parsoid='{}'></h1>
+
+<h2 data-parsoid='{}'></h2>
+
+<h3 data-parsoid='{}'></h3>
+
+<h4 data-parsoid='{}'></h4>
+
+<h5 data-parsoid='{}'></h5>
+
+<h6 data-parsoid='{}'></h6>
!! wikitext
=<nowiki/>=
@@ -21004,92 +22105,81 @@ parsoid
=====<nowiki/>=====
======<nowiki/>======
-!! html
-<h1></h1>
-<h2></h2>
-<h3></h3>
-<h4></h4>
-<h5></h5>
-<h6></h6>
!!end
!! test
Headings: 6a. Heading chars in SOL context (with trailing spaces)
!! options
-parsoid
+parsoid=html2wt
+!! html/parsoid
+<p>=a=</p>
+
+<p>=a=</p>
+
+<p>=a=</p>
!! wikitext
<nowiki>=a=</nowiki>
<nowiki>=a=</nowiki>
<nowiki>=a=</nowiki>
-
-<nowiki>=a=</nowiki>
-!! html
-<p>=a=</p>
-<p>=a= </p>
-<p>=a= </p>
-<p>=a= </p>
!!end
!! test
Headings: 6b. Heading chars in SOL context (with trailing newlines)
!! options
-parsoid
-!! wikitext
-<nowiki>=a=
-b</nowiki>
-
-<nowiki>=a=
-b</nowiki>
-
-<nowiki>=a=
-b</nowiki>
-
-<nowiki>=a=
-b</nowiki>
-!! html
+parsoid=html2wt
+!! html/parsoid
<p>=a=
b</p>
+
<p>=a=
b</p>
+
<p>=a=
b</p>
-<p>=a=
-b</p>
-</p>
+!! wikitext
+<nowiki>=a=</nowiki>
+b
+
+<nowiki>=a=</nowiki>
+b
+
+<nowiki>=a=</nowiki>
+b
!!end
!! test
Headings: 6c. Heading chars in SOL context (leading newline break)
!! options
-parsoid
+parsoid=html2wt
+!! html/parsoid
+<p>a
+=b=</p>
!! wikitext
a
<nowiki>=b=</nowiki>
-!! html
-<p>a
-=b=</p>
!!end
!! test
Headings: 6d. Heading chars in SOL context (with interspersed comments)
!! options
-parsoid
+parsoid=html2wt
+!! html/parsoid
+<!--c0--><p>=a=</p>
+
+<!--c1--><p>=a=</p> <!--c2--> <!--c3-->
!! wikitext
<!--c0--><nowiki>=a=</nowiki>
<!--c1--><nowiki>=a=</nowiki> <!--c2--> <!--c3-->
-!! html
-<p><!--c0-->=a=</p>
-<p><!--c1-->=a= <!--c2--> <!--c3--></p>
!!end
!! test
Headings: 6d. Heading chars in SOL context (No escaping needed)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
=a=<div>b</div>
!! wikitext
=a=<div>b</div>
@@ -21099,11 +22189,11 @@ parsoid=html2wt
Headings: 7. Insert a newline between new content and headings
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<h2>NEW</h2>
<p>new</p>
-<h2 data-parsoid='{"dsr":[0,5,2,2]}'>A</h2>
-<p data-parsoid='{"dsr":[6,7,0,0]}'>a</p>
+<h2 data-parsoid='{}'>A</h2>
+<p data-parsoid='{}'>a</p>
!! wikitext
== NEW ==
new
@@ -21126,21 +22216,36 @@ a
!! test
Lists: 0. Outside nests
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>*foo</p>
+
+<p>#foo</p>
+
+<p>;Foo:bar</p>
!! wikitext
<nowiki>*</nowiki>foo
<nowiki>#</nowiki>foo
-<nowiki>;Foo:</nowiki>bar
-!! html
-<p>*foo
-</p><p>#foo
-</p><p>;Foo:bar
-</p>
+<nowiki>;</nowiki>Foo<nowiki>:</nowiki>bar
!!end
!! test
Lists: 1. Nested inside html
+!! options
+parsoid=html2wt
+!! html/parsoid
+<ul><li>*foo</li></ul>
+<ul><li>#foo</li></ul>
+<ul><li>:foo</li></ul>
+<ul><li>;foo</li></ul>
+<ol><li>*foo</li></ol>
+<ol><li>#foo</li></ol>
+<ol><li>:foo</li></ol>
+<ol><li>;foo</li></ol>
+
!! wikitext
*<nowiki>*foo</nowiki>
@@ -21157,20 +22262,19 @@ Lists: 1. Nested inside html
#<nowiki>:foo</nowiki>
#<nowiki>;foo</nowiki>
-!! html
-<ul><li>*foo</li></ul>
-<ul><li>#foo</li></ul>
-<ul><li>:foo</li></ul>
-<ul><li>;foo</li></ul>
-<ol><li>*foo</li></ol>
-<ol><li>#foo</li></ol>
-<ol><li>:foo</li></ol>
-<ol><li>;foo</li></ol>
-
!!end
!! test
Lists: 2. Inside definition lists
+!! options
+parsoid=html2wt
+!! html/parsoid
+<dl><dt>;foo</dt></dl>
+<dl><dt>:foo</dt></dl>
+<dl><dt>:foo</dt>
+<dd>bar</dd></dl>
+<dl><dd>:foo</dd></dl>
+
!! wikitext
;<nowiki>;foo</nowiki>
@@ -21180,40 +22284,27 @@ Lists: 2. Inside definition lists
:bar
:<nowiki>:foo</nowiki>
-!! html
-<dl><dt>;foo</dt></dl>
-<dl><dt>:foo</dt></dl>
-<dl><dt>:foo</dt>
-<dd>bar</dd></dl>
-<dl><dd>:foo</dd></dl>
-
!!end
!! test
Lists: 3. Only bullets at start of text should be escaped
+!! options
+parsoid=html2wt
+!! html/parsoid
+<ul><li>*foo*bar</li></ul>
+<ul><li>*foo<i>it</i>*bar</li></ul>
+
!! wikitext
*<nowiki>*foo*bar</nowiki>
*<nowiki>*foo</nowiki>''it''*bar
-!! html
-<ul><li>*foo*bar</li></ul>
-<ul><li>*foo<i>it</i>*bar</li></ul>
-
!!end
!! test
Lists: 4. No escapes needed
!! options
-parsoid
-!! wikitext
-*foo*bar
-
-*''foo''*bar
-
-*[[Foo]]: bar
-
-*[[Foo]]*bar
-!! html
+parsoid=html2wt
+!! html/parsoid
<ul>
<li>foo*bar
</li>
@@ -21230,10 +22321,29 @@ parsoid
<li><a rel="mw:WikiLink" href="Foo" title="Foo">Foo</a>*bar
</li>
</ul>
+!! wikitext
+*foo*bar
+
+*''foo''*bar
+
+*[[Foo]]: bar
+
+*[[Foo]]*bar
!!end
!! test
Lists: 5. No unnecessary escapes
+!! options
+parsoid=html2wt
+!! html/parsoid
+<ul><li> bar <span>[[foo]]</span></li></ul>
+<ul><li> =bar <span>[[foo]]</span></li></ul>
+<ul><li> [[bar <span>[[foo]]</span></li></ul>
+<ul><li> ]]bar <span>[[foo]]</span></li></ul>
+<ul><li> =bar <span>foo]]</span>=</li></ul>
+<ul><li> <s></s>: a</li></ul>
+<ul><li> <i>* foo</i></li></ul>
+
!! wikitext
* bar <span><nowiki>[[foo]]</nowiki></span>
@@ -21248,22 +22358,13 @@ Lists: 5. No unnecessary escapes
* <s></s>: a
* ''* foo''
-!! html
-<ul><li> bar <span>[[foo]]</span></li></ul>
-<ul><li> =bar <span>[[foo]]</span></li></ul>
-<ul><li> [[bar <span>[[foo]]</span></li></ul>
-<ul><li> ]]bar <span>[[foo]]</span></li></ul>
-<ul><li> =bar <span>foo]]</span>=</li></ul>
-<ul><li> <s></s>: a</li></ul>
-<ul><li> <i>* foo</i></li></ul>
-
!!end
!! test
Lists: 6. Escape bullets in SOL position
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p><!--cmt-->*foo</p>
!! wikitext
<!--cmt--><nowiki>*</nowiki>foo
@@ -21271,20 +22372,22 @@ parsoid=html2wt
!! test
Lists: 7. Escape bullets in a multi-line context
-!! wikitext
-a
-<nowiki>*</nowiki>b
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<p>a
*b
</p>
+!! wikitext
+a
+<nowiki>*</nowiki>b
!!end
!! test
Lists: 8. Escape colons only if not present in tags
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<dl><dt>a:b<i>c:d</i></dt></dl>
!! wikitext
; <nowiki>a:b</nowiki>''c:d''
@@ -21296,17 +22399,16 @@ parsoid=html2wt
!! test
HRs: 1. Single line
+!! options
+parsoid=html2wt
+!! html/parsoid
+<hr />----
+<hr />=foo=
+<hr />*foo
!! wikitext
----<nowiki>----</nowiki>
----=foo=
----*foo
-!! html+tidy
-<hr />
-<p>----</p>
-<hr />
-<p>=foo=</p>
-<hr />
-<p>*foo</p>
!! end
#### --------------- Tables ---------------
@@ -21330,40 +22432,48 @@ HRs: 1. Single line
!! test
Tables: 1a. Simple example
-!! wikitext
-<nowiki>{|
-|}</nowiki>
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<p>{|
|}
</p>
+!! wikitext
+<nowiki>{|</nowiki>
+|}
!! end
!! test
Tables: 1b. No escaping needed
-!! wikitext
-!foo
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<p>!foo
</p>
+!! wikitext
+!foo
!! end
!! test
Tables: 1c. No escaping needed
-!! wikitext
-|foo
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<p>|foo
</p>
+!! wikitext
+|foo
!! end
!! test
Tables: 1d. No escaping needed
-!! wikitext
-|}foo
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<p>|}foo
</p>
+!! wikitext
+|}foo
!! end
!! test
@@ -21424,11 +22534,8 @@ parsoid=html2wt
!! test
Tables: 2c. Nested in td -- no escaping needed
-!! wikitext
-{|
-
-|foo!!bar
-|}
+!! options
+parsoid=html2wt
!! html/*
<table>
@@ -21436,15 +22543,17 @@ Tables: 2c. Nested in td -- no escaping needed
<td>foo!!bar
</td></tr></table>
-!! end
-
-!! test
-Tables: 3a. Nested in th
!! wikitext
{|
-!foo!bar
+|foo!!bar
|}
+!! end
+
+!! test
+Tables: 3a. Nested in th
+!! options
+parsoid=html2wt
!! html/*
<table>
@@ -21452,6 +22561,11 @@ Tables: 3a. Nested in th
<th>foo!bar
</th></tr></table>
+!! wikitext
+{|
+
+!foo!bar
+|}
!! end
!! test
@@ -21560,6 +22674,19 @@ parsoid=html2wt
!! test
Tables: 4c. No escaping needed
+!! options
+parsoid=html2wt
+!! html/parsoid
+<table><tbody>
+<tr><td>foo-bar</td><td>foo+bar</td></tr>
+<tr><td><i>foo</i>-bar</td><td><i>foo</i>+bar</td></tr>
+<tr><td>foo
+<p>bar|baz
++bar
+-bar</p></td></tr>
+<tr><td>x
+<div>a|b</div></td>
+</tbody></table>
!! wikitext
{|
|foo-bar
@@ -21600,21 +22727,18 @@ bar|baz
<div>a|b</div>
</td></tr></table>
-!! html/parsoid
-<table><tbody>
-<tr><td>foo-bar</td><td>foo+bar</td></tr>
-<tr><td><i>foo</i>-bar</td><td><i>foo</i>+bar</td></tr>
-<tr><td>foo
-<p>bar|baz
-+bar
--bar</p></td></tr>
-<tr><td>x
-<div>a|b</div></td>
-</tbody></table>
!! end
!! test
Tables: 4d. No escaping needed
+!! options
+parsoid=html2wt
+!! html/parsoid
+<table>
+<tbody><tr><td><a rel="mw:WikiLink" href="./Foo" title="Foo">Foo</a>-bar</td>
+<td data-parsoid='{"startTagSrc":"|","attrSepSrc":"|"}'>+1</td>
+<td data-parsoid='{"startTagSrc":"|","attrSepSrc":"|"}'>-2</td></tr>
+</tbody></table>
!! wikitext
{|
|[[Foo]]-bar
@@ -21631,29 +22755,42 @@ Tables: 4d. No escaping needed
<td>-2
</td></tr></table>
+!! end
+
+!! test
+T97430: Don't emit empty nowiki pairs around marker meta tags
+!! options
+parsoid=html2wt
!! html/parsoid
-<table>
-<tbody><tr><td><a rel="mw:WikiLink" href="./Foo" title="Foo">Foo</a>-bar</td>
-<td data-parsoid='{"startTagSrc":"|","attrSepSrc":"|"}'>+1</td>
-<td data-parsoid='{"startTagSrc":"|","attrSepSrc":"|"}'>-2</td></tr>
-</tbody></table>
+<p>*This is a long sentence here that will make the nowiki algo split up the nowikis into multiple pairs
+|** Make this another long long long sentence forcing the nowiki algo to split up the nowikis.</p>
+!! wikitext
+<nowiki>*</nowiki>This is a long sentence here that will make the nowiki algo split up the nowikis into multiple pairs
+|** Make this another long long long sentence forcing the nowiki algo to split up the nowikis.
!! end
!! test
-Tables: Digest broken attributes on table and tr tag
+Unclosed xmlish element in table line shouldn't eat end delimiters
!! options
-parsoid=wt2html
+parsoid=html2wt
+!! html/parsoid
+<table>
+<tbody><tr><td> &lt;foo</td>
+<td> bar></td></tr>
+</tbody></table>
!! wikitext
-{| || |} ++
-|- || || ++ --
-|- > [
+{|
+| <foo
+| bar>
|}
-!! html
+!! html/php
<table>
-<tbody>
-<tr></tr>
-<tr></tr>
-</tbody></table>
+<tr>
+<td> &lt;foo
+</td>
+<td> bar&gt;
+</td></tr></table>
+
!! end
#### --------------- Links ----------------
@@ -21665,6 +22802,12 @@ parsoid=wt2html
#### --------------------------------------
!! test
Links 1. WikiLinks: No escapes needed
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="Foo" title="Foo">Foo<i>boo</i></a>
+<a rel="mw:WikiLink" href="Foo" title="Foo">[Foobar]</a>
+<a rel="mw:WikiLink" href="Foo" title="Foo">x [Foobar] x</a></p>
!! wikitext
[[Foo|Foo''boo'']]
[[Foo|[Foobar]]]
@@ -21674,10 +22817,6 @@ Links 1. WikiLinks: No escapes needed
<a href="/wiki/Foo" title="Foo">[Foobar]</a>
<a href="/wiki/Foo" title="Foo">x [Foobar] x</a>
</p>
-!! html/parsoid
-<p><a rel="mw:WikiLink" href="Foo" title="Foo">Foo<i>boo</i></a>
-<a rel="mw:WikiLink" href="Foo" title="Foo">[Foobar]</a>
-<a rel="mw:WikiLink" href="Foo" title="Foo">x [Foobar] x</a></p>
!! end
!! test
@@ -21722,6 +22861,11 @@ parsoid=html2wt
!! test
Links 3. WikiLinks: No escapes needed
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="Foo">[Foobar</a>
+<a rel="mw:WikiLink" href="Foo" title="Foo">foo|bar</a></p>
!! wikitext
[[Foo|[Foobar]]
[[Foo|foo|bar]]
@@ -21729,9 +22873,6 @@ Links 3. WikiLinks: No escapes needed
<p><a href="/wiki/Foo" title="Foo">[Foobar</a>
<a href="/wiki/Foo" title="Foo">foo|bar</a>
</p>
-!! html/parsoid
-<p><a rel="mw:WikiLink" href="Foo">[Foobar</a>
-<a rel="mw:WikiLink" href="Foo" title="Foo">foo|bar</a></p>
!! end
!! test
@@ -21761,17 +22902,21 @@ parsoid=html2wt
!! test
Links 5. ExtLinks: No escapes needed
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://google.com">[google</a></p>
!! wikitext
[http://google.com [google]
!! html/php
<p><a rel="nofollow" class="external text" href="http://google.com">[google</a>
</p>
-!! html/parsoid
-<p><a rel="mw:ExtLink" href="http://google.com">[google</a></p>
!! end
!! test
Links 6. Add <nowiki/>s between text-nodes and url-links when required (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
<p>x<a rel="mw:ExtLink" href="http://example.com" data-parsoid='{"stx":"url"}'>http://example.com</a>y
<a rel="mw:ExtLink" href="http://example.com" data-parsoid='{"stx":"url"}'>http://example.com</a>?x
@@ -21805,6 +22950,8 @@ http://example.com(x<nowiki/>)
!! test
Links 7a. Don't add spurious <nowiki/>s between text-nodes and url-links (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
<p>x
<a rel="mw:ExtLink" href="http://example.com" data-parsoid='{"stx":"url"}'>http://example.com</a>
@@ -21838,6 +22985,8 @@ y
!! test
Links 7b. Don't add spurious <nowiki/>s between text-nodes and url-links (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
<p><a rel="mw:ExtLink" href="http://example.com" data-parsoid='{"stx":"url"}'>http://example.com</a>.,;:!?\
-<a rel="mw:ExtLink" href="http://example.com">http://example.com</a>:</p>
@@ -21852,6 +23001,8 @@ http://example.com.,;:!?\
!! test
Links 8. Add <nowiki/>s between text-nodes and RFC-links when required (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
<p><a href="//tools.ietf.org/html/rfc123" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>RFC 123</a>4
<a href="//tools.ietf.org/html/rfc123" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>RFC 123</a>y
@@ -21864,6 +23015,8 @@ X<nowiki/>RFC 123<nowiki/>y
!! test
Links 9. Don't add spurious <nowiki/>s between text-nodes and RFC-links (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
<p><a href="//tools.ietf.org/html/rfc123" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>RFC 123</a>?foo
<a href="//tools.ietf.org/html/rfc123" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>RFC 123</a>&amp;foo
@@ -21882,6 +23035,8 @@ RFC 123&foo
!! test
Links 10. Add <nowiki/>s between text-nodes and PMID-links when required (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
<p><a href="//www.ncbi.nlm.nih.gov/pubmed/123?dopt=Abstract" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>PMID 123</a>4
<a href="//www.ncbi.nlm.nih.gov/pubmed/123?dopt=Abstract" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>PMID 123</a>y
@@ -21894,6 +23049,8 @@ X<nowiki/>PMID 123<nowiki/>y
!! test
Links 11. Don't add spurious <nowiki/>s between text-nodes and PMID-links (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
<p><a href="//www.ncbi.nlm.nih.gov/pubmed/123?dopt=Abstract" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>PMID 123</a>?foo
<a href="//www.ncbi.nlm.nih.gov/pubmed/123?dopt=Abstract" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>PMID 123</a>&foo
@@ -21912,10 +23069,12 @@ PMID 123&foo
!! test
Links 12. Add <nowiki/>s between text-nodes and ISBN-links when required (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
-<p><a href="./Special:BookSources/1234567890" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>1
-<a href="./Special:BookSources/1234567890" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>x
-a<a href="./Special:BookSources/1234567890" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>b
+<p><a href="./Special:BookSources/1234567890" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>1
+<a href="./Special:BookSources/1234567890" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>x
+a<a href="./Special:BookSources/1234567890" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>b
</p>
!! wikitext
ISBN 1234567890<nowiki/>1
@@ -21925,8 +23084,10 @@ a<nowiki/>ISBN 1234567890<nowiki/>b
!! test
Links 13. Don't add spurious <nowiki/>s between text-nodes and ISBN-links (bug 64300)
+!! options
+parsoid=html2wt
!! html/parsoid
-<p>-<a href="./Special:BookSources/1234567890" rel="mw:ExtLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>'s
+<p>-<a href="./Special:BookSources/1234567890" rel="mw:WikiLink" data-parsoid='{"stx":"magiclink"}'>ISBN 1234567890</a>'s
!! wikitext
-ISBN 1234567890's
!! html/php
@@ -21942,20 +23103,21 @@ parsoid=html2wt
<p>this is not a link: http://example.com
</p>
!! wikitext
-this is not a link: <nowiki>http://example.com</nowiki>
+<nowiki>this is not a link: http://example.com</nowiki>
!! end
!! test
Links 15. Link trails can't become link prefixes.
!! options
language=is
+parsoid=html2wt
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="Söfnuður" title="Söfnuður" data-parsoid='{"stx":"simple","tail":"-"}'>Söfnuður-</a><a rel="mw:WikiLink" href="00" title="00">00</a></p>
!! wikitext
[[Söfnuður]]-[[00]]
!! html/php
<p><a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">Söfnuður-</a><a href="/wiki/00" title="00">00</a>
</p>
-!! html/parsoid
-<p><a rel="mw:WikiLink" href="Söfnuður" title="Söfnuður" data-parsoid='{"stx":"simple","tail":"-"}'>Söfnuður-</a><a rel="mw:WikiLink" href="00" title="00">00</a></p>
!! end
#### --------------- Quotes ---------------
@@ -21967,28 +23129,7 @@ language=is
!! test
1a. Quotes inside <b> and <i>
!! options
-parsoid=html2wt,wt2wt
-!! wikitext
-''<nowiki/>'foo'''
-''<nowiki>''foo''</nowiki>''
-''<nowiki>'''foo'''</nowiki>''
-''foo''<nowiki/>'s
-'''<nowiki/>'foo''''
-'''<nowiki>''foo''</nowiki>'''
-'''<nowiki>'''foo'''</nowiki>'''
-'''foo'<nowiki/>''bar'<nowiki/>''baz'''
-'''foo'''<nowiki/>'s
-'''foo''
-''foo''<nowiki/>'
-''foo'''<nowiki/>'
-'''foo''<nowiki/>'
-''''foo'''
-'''foo'''<nowiki/>'
-''''foo'''<nowiki/>'
-''fools'<span> errand</span>''
-''<span>fool</span>'s errand''
-'<nowiki/>''foo'' bar '''baz''
-a|!*#-:;+-~[]{}b'''x''
+parsoid=html2wt
!! html/*
<p><i>'foo'</i>
<i>''foo''</i>
@@ -22011,12 +23152,44 @@ a|!*#-:;+-~[]{}b'''x''
'<i>foo</i> bar '<i>baz</i>
a|!*#-:;+-~[]{}b'<i>x</i>
</p>
+!! wikitext
+''<nowiki/>'foo'''
+''<nowiki>''foo''</nowiki>''
+''<nowiki>'''foo'''</nowiki>''
+''foo''<nowiki/>'s
+'''<nowiki/>'foo''''
+'''<nowiki>''foo''</nowiki>'''
+'''<nowiki>'''foo'''</nowiki>'''
+'''foo'<nowiki/>''bar'<nowiki/>''baz'''
+'''foo'''<nowiki/>'s
+'''foo''
+''foo''<nowiki/>'
+''foo'''<nowiki/>'
+'''foo''<nowiki/>'
+''''foo'''
+'''foo'''<nowiki/>'
+''''foo'''<nowiki/>'
+''fools'<span> errand</span>''
+''<span>fool</span>'s errand''
+'<nowiki/>''foo'' bar '''baz''
+a|!*#-:;+-~[]{}b'''x''
!! end
!! test
1b. Quotes inside <b> and <i> with other tags on same line
!! options
-parsoid=html2wt,wt2wt
+parsoid=html2wt
+!! html/parsoid
+'<i>a</i> foo <i><a rel="mw:WikiLink" href="Bar" title="Bar">bar</a></i>
+<i>a'</i> foo <i><a rel="mw:WikiLink" href="Bar" title="Bar">bar</a></i>
+<i>a'</i> foo <b><a rel="mw:WikiLink" href="Bar" title="Bar" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[bar]]"}},"i":0}}]}'>bar</a></b>
+<a rel="mw:WikiLink" href="Foo" title="Foo">foo</a> x'<i><a href="Bar" rel="mw:WikiLink" title="Bar">bar</a></i>
+'<i>foo</i> <span class="mw-ref" id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span>
+'<i>foo</i> <div title="name">test</div>
+'<i>foo</i> and <br data-parsoid='{"stx":"html","noClose":true}'/> bar
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">test</span></li>
+</ol>
!! wikitext
'''a'' foo ''[[bar]]''
''a''' foo ''[[bar]]''
@@ -22026,56 +23199,49 @@ parsoid=html2wt,wt2wt
'''foo'' <div title="name">test</div>
'''foo'' and <br> bar
<references />
-!! html
-'<i>a</i> foo <i><a rel="mw:WikiLink" href="Bar" title="Bar">bar</a></i>
-<i>a'</i> foo <i><a rel="mw:WikiLink" href="Bar" title="Bar">bar</a></i>
-<i>a'</i> foo <b><a rel="mw:WikiLink" href="Bar" title="Bar" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[bar]]"}},"i":0}}]}'>bar</a></b>
-<a rel="mw:WikiLink" href="Foo" title="Foo">foo</a> x'<i><a href="Bar" rel="mw:WikiLink" title="Bar">bar</a></i>
-'<i>foo</i> <span class="reference" id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span>
-'<i>foo</i> <div title="name">test</div>
-'<i>foo</i> and <br data-parsoid='{"stx":"html","noClose":true}'/> bar
-<ol class="references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">test</span></li>
-</ol>
!! end
!! test
2. Link fragments separated by <i> and <b> tags
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>[[<i>foo</i>hello]]</p>
+<p>[[<b>foo</b>hello]]</p>
!! wikitext
[[''foo''<nowiki>hello]]</nowiki>
[['''foo'''<nowiki>hello]]</nowiki>
-!! html
-<p>[[<i>foo</i>hello]]
-</p><p>[[<b>foo</b>hello]]
-</p>
!! end
# FIXME: Escaping one or both of [[ and ]] is also acceptable --
# this is one of the shortcomings of this format
!! test
3. Link fragments inside <i> and <b>
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p><i>[[foo</i>]]</p>
+<p><b>[[foo</b>]]</p>
!! wikitext
''[[foo''<nowiki>]]</nowiki>
'''[[foo'''<nowiki>]]</nowiki>
-!! html
-<p><i>[[foo</i>]]
-</p><p><b>[[foo</b>]]
-</p>
!! end
!! test
4. No escaping needed
-!! wikitext
-'<span>''bar''</span>'
-'<span>'''bar'''</span>'
-'a:b'foo
-!! html
+!! options
+options=html2wt
+!! html/parsoid
<p>'<span><i>bar</i></span>'
'<span><b>bar</b></span>'
'a:b'foo
</p>
+!! wikitext
+'<span>''bar''</span>'
+'<span>'''bar'''</span>'
+'a:b'foo
!! end
#### ----------- Paragraphs ---------------
@@ -22084,6 +23250,15 @@ parsoid=html2wt,wt2wt
!! test
1. No unnecessary escapes
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>bar <span>[[foo]]</span>
+</p><p>=bar <span>[[foo]]</span>
+</p><p>[[bar <span>[[foo]]</span>
+</p><p>]]bar <span>[[foo]]</span>
+</p><p>=bar <span>foo]]</span>=
+</p>
!! wikitext
bar <span><nowiki>[[foo]]</nowiki></span>
@@ -22094,13 +23269,6 @@ bar <span><nowiki>[[foo]]</nowiki></span>
]]bar <span><nowiki>[[foo]]</nowiki></span>
=bar <span>foo]]</span><nowiki>=</nowiki>
-!! html
-<p>bar <span>[[foo]]</span>
-</p><p>=bar <span>[[foo]]</span>
-</p><p>[[bar <span>[[foo]]</span>
-</p><p>]]bar <span>[[foo]]</span>
-</p><p>=bar <span>foo]]</span>=
-</p>
!!end
#### ----------------------- PRE --------------------------
@@ -22109,101 +23277,136 @@ bar <span><nowiki>[[foo]]</nowiki></span>
!! test
1. Leading whitespace in SOL context should be escaped
!! options
-parsoid
+parsoid=html2wt
+!! html/parsoid
+<p> a</p>
+
+<p> a</p>
+
+<p> a(tab)</p>
+
+<p> a
+<!--cmt-->
+ a</p>
+
+<p>a
+ b</p>
+
+<p>a
+ b</p>
+
+<p>a
+ b</p>
!! wikitext
<nowiki> </nowiki>a
<nowiki> </nowiki> a
-<nowiki> </nowiki>a(tab)
+ a(tab)
<nowiki> </nowiki> a
<!--cmt-->
-<nowiki> </nowiki> a
+<nowiki> </nowiki>a
a
<nowiki> </nowiki>b
a
-<nowiki> </nowiki>b
+ b
a
-<nowiki> </nowiki> b
-!! html
-<p> a</p>
-<p> a</p>
-<p> a(tab)</p>
-<p> a</p>
-<p><!--cmt--> a</p>
-<p>a
- b</p>
-<p>a
- b</p>
-<p>a
- b</p>
+ b
+!! html/php
+<p> a
+</p><p> a
+</p><p> a(tab)
+</p><p> a
+ a
+</p><p>a
+ b
+</p><p>a
+ b
+</p><p>a
+ b
+</p>
!! end
!! test
2. Leading whitespace in non-indent-pre contexts should not be escaped
!! options
-parsoid
+parsoid=htm2wt
+!! html/parsoid
+<p>foo <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
+<ol class="mw-references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1"><a href="#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><i data-parsoid='{"dsr":[9,14,2,2]}'>a</i>
+ b</span></li>
+</ol>
!! wikitext
foo <ref>''a''
b</ref>
<references />
-!! html
-<p>foo <span about="#mwt2" class="reference" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1">[1]</a></span></p>
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><i data-parsoid='{"dsr":[9,14,2,2]}'>a</i>
- b</span></li>
-</ol>
!! end
!! test
3. Leading whitespace in indent-pre suppressing contexts should not be escaped
!! options
-parsoid
-!! wikitext
+parsoid=html2wt
+!! html/parsoid
<blockquote>
+<p>
a
<span>b</span>
- c
+ c</p>
</blockquote>
-!! html
+!! wikitext
<blockquote>
-<p>
a
<span>b</span>
- c</p>
+ c
</blockquote>
!! end
!! test
4. Leading whitespace in indent-pre suppressing contexts should not be escaped
!! options
-parsoid
+options=html2wt
+!! html/parsoid
+ <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
!! wikitext
[[File:Foobar.jpg|thumb|caption]]
-!! html/parsoid
- <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
!! end
!! test
5. Nowiki escaping should account for indent-pres
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<pre>==foo==</pre>
!! wikitext
==foo==
!! end
+!!test
+T95794: nowiki escaping should account for leading space at start-of-line in an indent-pre block
+!! options
+parsoid=html2wt
+!! html/parsoid
+<pre>
+* foo
+* bar
+</pre>
+!! wikitext
+ * foo
+ * bar
+!! end
+
#### --------------- Behavior Switches --------------------
+
!! test
1. Valid behavior switches should be escaped
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
__TOC__
<i>__TOC__</i>
!! wikitext
@@ -22215,7 +23418,7 @@ __TOC__
2. Invalid behavior switches should not be escaped
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
__TOO__
__|__
!! wikitext
@@ -22223,6 +23426,31 @@ __TOO__
__|__
!! end
+# We use indent-pre as an indirect way to test for sol-transparent behavior.
+!! test
+Behavior switches should be SOL-transparent
+!! options
+parsoid=html2wt
+!! html/parsoid
+ <meta property="mw:PageProp/toc" />
+
+ <!-- this one's bogus -->
+<pre>__TOO__</pre>
+
+<pre data-parsoid='{}'><meta property="mw:PageProp/toc" data-parsoid='{"src":"__TOC__","magicSrc":"__TOC__"}'/> foo</pre>
+
+<meta property="mw:PageProp/toc" data-parsoid='{"src":"__TOC__","magicSrc":"__TOC__"}'/><pre data-parsoid='{}'>bar</pre>
+!! wikitext
+ __TOC__
+
+ <!-- this one's bogus -->
+ __TOO__
+
+ __TOC__ foo
+
+__TOC__ bar
+!! end
+
#### --------------- HTML tags ---------------
#### 1. a tags
#### 2. other tags
@@ -22232,75 +23460,85 @@ __|__
!! test
1. a tags
!! options
-parsoid
+parsoid=html2wt
+!! html/parsoid
+&lt;a href=&quot;http://google.com&quot;&gt;google&lt;/a&gt;
!! wikitext
<a href="http://google.com">google</a>
-!! html
-&lt;a href=&quot;http://google.com&quot;&gt;google&lt;/a&gt;
!! end
!! test
2. other tags
-!! wikitext
-* <nowiki><div>foo</div></nowiki>
-* <nowiki><div style="color:red">foo</div></nowiki>
-* <nowiki><td></nowiki>
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<ul><li> &lt;div&gt;foo&lt;/div&gt;</li>
<li> &lt;div style=&quot;color:red&quot;&gt;foo&lt;/div&gt;</li>
<li> &lt;td&gt;</li></ul>
+!! wikitext
+* <nowiki><div>foo</div></nowiki>
+* <nowiki><div style="color:red">foo</div></nowiki>
+* <nowiki><td></nowiki>
!! end
!! test
3. multi-line html tag
-!! wikitext
-<nowiki><div
->foo</div
-></nowiki>
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<p>&lt;div
&gt;foo&lt;/div
&gt;
</p>
+!! wikitext
+<nowiki><div
+>foo</div
+></nowiki>
!! end
!! test
4. extension tags
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>&lt;ref&gt;foo&lt;/ref&gt;
+</p><p>&lt;ref&gt;bar
+</p><p>baz&lt;/ref&gt;
+</p>
!! wikitext
<nowiki><ref>foo</ref></nowiki>
<nowiki><ref>bar</nowiki>
baz<nowiki></ref></nowiki>
-!! html
-<p>&lt;ref&gt;foo&lt;/ref&gt;
-</p><p>&lt;ref&gt;bar
-</p><p>baz&lt;/ref&gt;
-</p>
!! end
#### --------------- Others ---------------
!! test
Escaping nowikis
-!! wikitext
-&lt;nowiki&gt;foo&lt;/nowiki&gt;
-!! html
+!! options
+parsoid=html2wt
+!! html/parsoid
<p>&lt;nowiki&gt;foo&lt;/nowiki&gt;
</p>
+!! wikitext
+&lt;nowiki&gt;foo&lt;/nowiki&gt;
!! end
## The quote-char in the input is necessary for triggering the bug
!! test
(Bug 52035) Nowiki-escaping should not get tripped by " :" in text
!! options
-parsoid=wt2wt,html2wt
+parsoid=html2wt
+!! html/parsoid
+<p>foo's bar :</p>
!! wikitext
foo's bar :
-!! html
-<p>foo's bar :</p>
!! end
+#----------- End of wikitext escaping tests --------------
+
!! test
Tag-like HTML structures are passed through as text
@@ -22352,20 +23590,9 @@ HTML tag with broken attribute value quoting
!! wikitext
<span title="Hello world>Foo</span>
!! html/php
-<p><span>Foo</span>
-</p>
-!! html/parsoid
<p><span title="Hello world">Foo</span>
</p>
-!! end
-
-!! test
-Parsoid-only: HTML tag with broken attribute value quoting
-!! options
-parsoid
-!! wikitext
-<span title="Hello world>Foo</span>
-!! html
+!! html/parsoid
<p><span title="Hello world">Foo</span>
</p>
!! end
@@ -22379,7 +23606,7 @@ Table with broken attribute value quoting
!! html/php
<table>
<tr>
-<td>Foo
+<td title="Hello world">Foo
</td></tr></table>
!! html/parsoid
@@ -22400,9 +23627,9 @@ Table with broken attribute value quoting on consecutive lines
!! html/php
<table>
<tr>
-<td>Foo
+<td title="Hello world">Foo
</td>
-<td>Bar
+<td style="color:red">Bar
</td></tr></table>
!! html/parsoid
@@ -22415,7 +23642,7 @@ Table with broken attribute value quoting on consecutive lines
!! end
!! test
-Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353)
+2. Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353)
!! options
parsoid
!! wikitext
@@ -22425,7 +23652,7 @@ parsoid
!! end
!! test
-Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353)
+1. Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353)
!! options
parsoid
!! wikitext
@@ -22544,6 +23771,8 @@ bar
</tbody></table>
!!end
+# Note that the "style" attribute is really a template parameter here.
+# The = would have to be {{=}} if you wanted the literal.
!!test
Empty TD followed by TD with tpl-generated attribute
!! wikitext
@@ -22704,7 +23933,7 @@ Multi-line image caption generated by templates with/without trailing newlines
New element inserted (without intervening newlines) after an old sol-transparent node should serialize correctly
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>foo&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><p>new para</p>
<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{}'/><h1>new heading</h1>
@@ -22721,12 +23950,10 @@ new para
## a Parsoid serializer test, marking this Parsoid only
!!test
Improperly nested inline or quotes tags with whitespace in between
-!!options
-parsoid
!! wikitext
<span> <s>x</span> </s>
''' ''x''' ''
-!! html
+!! html/parsoid
<p><span> <s>x</s></span><s> </s>
<b> <i>x</i></b><i> </i>
</p>
@@ -22734,12 +23961,10 @@ parsoid
!!test
Encapsulate protected attributes from wt
-!!options
-parsoid
!! wikitext
-<div typeof="mw:placeholder stuff" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div>
-!! html
-<body><div data-x-typeof="mw:placeholder stuff" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
+<div typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div>
+!! html/parsoid
+<body><div data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
</body>
!!end
@@ -22752,7 +23977,7 @@ Ensure ParagraphWrapper can deal with stray closing pre tags
parsoid=wt2html
!! wikitext
plain text</pre>
-!! html
+!! html/parsoid
plain text
!!end
@@ -22762,7 +23987,7 @@ plain text
parsoid=wt2html
!! wikitext
<table>hi</table><table>ho</table>
-!! html
+!! html/parsoid
<p>hi</p>
<table></table>
<p>ho</p>
@@ -22778,7 +24003,7 @@ parsoid=wt2html,wt2wt
<tr> || ||
<td> a
</table>
-!! html
+!! html/parsoid
<p> || ||
</p><table>
<tbody><tr><td> a</td></tr>
@@ -22791,7 +24016,7 @@ Encapsulation properly handles null DSR information from foster box
parsoid=wt2html,wt2wt
!! wikitext
{{echo|<table>foo<tr><td>bar</td></tr></table>}}
-!! html
+!! html/parsoid
<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;<table>foo<tr><td>bar</td></tr></table>&quot;}},&quot;i&quot;:0}}]}">foo</span><table><tbody><tr><td>bar</td></tr></tbody></table>
!!end
@@ -22801,7 +24026,7 @@ parsoid=wt2html,wt2wt
parsoid=wt2wt,wt2html
!! wikitext
<table>{{echo|foo<tr><td>bar</td></tr>}}</table>
-!! html
+!! html/parsoid
<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo<tr><td>bar</td></tr>&quot;}},&quot;i&quot;:0}},&quot;</table>&quot;]}">foo</p><table>
<tbody>
<tr>
@@ -22817,7 +24042,7 @@ parsoid=wt2wt,wt2html
parsoid=wt2wt,wt2html
!! wikitext
<table><div>{{echo|foo}}</div><tr><td>bar</td></tr></table>
-!! html
+!! html/parsoid
<div typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><div>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo&quot;}},&quot;i&quot;:0}},&quot;</div><tr><td>bar</td></tr></table>&quot;]}">foo</div>
<table>
<tbody>
@@ -22834,7 +24059,7 @@ parsoid=wt2wt,wt2html
parsoid=wt2wt,wt2html
!! wikitext
<table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table>
-!! html
+!! html/parsoid
<div typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div><tr><td>&quot;}},&quot;i&quot;:0}},&quot;bar</td></tr></table>&quot;]}">
<p>foo</p>
</div>
@@ -22853,7 +24078,7 @@ parsoid=wt2wt,wt2html
parsoid=wt2wt,wt2html
!! wikitext
<table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table>
-!! html
+!! html/parsoid
<div typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div><tr><td>&quot;}},&quot;i&quot;:0}},&quot;bar</td></tr></table>&quot;]}">
<p>foo</p>
</div>
@@ -22872,7 +24097,7 @@ parsoid=wt2wt,wt2html
parsoid=wt2wt,wt2html
!! wikitext
<table><tr><td><div><p>{{echo|foo</p></div></td>foo}}</tr></table>
-!! html
+!! html/parsoid
<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><tr><td><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div></td>foo&quot;}},&quot;i&quot;:0}},&quot;</tr></table>&quot;]}">foo</p>
<table>
<tbody>
@@ -22893,7 +24118,7 @@ parsoid=wt2wt,wt2html
parsoid=wt2wt,wt2html
!! wikitext
<table><tr><td><div><p>{{echo|foo</p></div></td>foo</tr></table>}}<p>ok</p>
-!! html
+!! html/parsoid
<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><tr><td><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div></td>foo</tr></table>&quot;}},&quot;i&quot;:0}}]}">foo</p>
<table>
<tbody>
@@ -22915,7 +24140,7 @@ parsoid=wt2wt,wt2html
parsoid=wt2wt,wt2html
!! wikitext
<table>{{echo|<p>foo</p>}}<td>bar</td></table>
-!! html
+!! html/parsoid
<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;<p>foo</p>&quot;}},&quot;i&quot;:0}},&quot;<td>bar</td></table>&quot;]}">foo</p>
<table>
<tbody>
@@ -22926,6 +24151,8 @@ parsoid=wt2wt,wt2html
</table>
!!end
+# Note that the wt is broken on purpose: the = should be {{=}} if you
+# don't want it to be a template parameter key.
!!test
8. Encapsulate foster-parented transclusion content
!!options
@@ -22936,8 +24163,11 @@ parsoid=wt2wt,wt2html
|-
|b
|}
-!! html
-<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;a\n&quot;}},&quot;i&quot;:0}}]}">a</p><p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;{|&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;style&quot;:{&quot;wt&quot;:&quot;'color:red'&quot;}},&quot;i&quot;:0}},&quot;\n|-\n|b\n|}&quot;]}">{{{1}}}</p><table>
+!! html/parsoid
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n"}},"i":0}}]}'>a</p>
+<span> </span>
+<p typeof="mw:Transclusion" data-mw='{"parts":["{|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"style":{"wt":"&#39;color:red&#39;"}},"i":0}},"\n|-\n|b\n|}"]}'>{{{1}}}</p>
+<table>
<tbody>
<tr>
<td>b</td>
@@ -22952,7 +24182,7 @@ parsoid=wt2wt,wt2html
parsoid=wt2wt,wt2html
!! wikitext
<table>{{echo|hi</table>hello}}
-!! html
+!! html/parsoid
<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["&lt;table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;/table>hello"}},"i":0}}]}' data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"pi":[[{"k":"1","spc":["","","",""]}]]}'>hi</p><table about="#mwt2" data-parsoid='{"stx":"html"}'></table><p about="#mwt2">hello</p>
!!end
@@ -22967,7 +24197,7 @@ parsoid=wt2html,wt2wt
|}
</div>
|}
-!! html
+!! html/parsoid
<div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"OpenTable","href":"./Template:OpenTable"},"params":{},"i":0}},"\n&lt;div>"]}' data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[]]}'></div><span about="#mwt1">
</span>
<table about="#mwt1" data-parsoid='{"autoInsertedEnd":true}'></table>
@@ -22995,7 +24225,7 @@ Properly encapsulate empty-content transclusions in fosterable positions
Support <object> element with .data attribute
!!options
parsoid=html2wt
-!! html
+!! html/parsoid
<object data="test.swf"></object>
!! wikitext
<object data="test.swf"></object>
@@ -23024,7 +24254,7 @@ Don't block XML namespace declaration
Serialize interwiki links pointing to the current wiki as plain wiki links (bug 65869)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p><a rel="mw:ExtLink" href="http://mi.wikipedia.org/wiki/Foo">Foo</a></p>
!! wikitext
[[Foo]]
@@ -23035,7 +24265,7 @@ parsoid=html2wt
New wikilinks should be serialized properly
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<a rel="mw:WikiLink" href="./Foo" title="Foo" data-parsoid='{}'>Foo</a>
<a rel="mw:WikiLink" href="./Foo" title="Foo">Foo</a>
!! wikitext
@@ -23047,7 +24277,7 @@ parsoid=html2wt
New wiki links (href variations)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<a rel="mw:WikiLink" href="./Foo_bar">Foo_bar</a>
<a rel="mw:WikiLink" href="Foo_bar">Foo_bar</a>
<a rel="mw:WikiLink" href="Foo bar">Foo_bar</a>
@@ -23063,7 +24293,7 @@ parsoid=html2wt
New wiki links (content string variations)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<a rel="mw:WikiLink" href="./Foo_bar">Foo_bar</a>
<a rel="mw:WikiLink" href="./Foo_bar">Foo bar</a>
<a rel="mw:WikiLink" href="./Foo_bar">./Foo_bar</a>
@@ -23077,7 +24307,7 @@ parsoid=html2wt
New category links (href variations)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<link rel="mw:PageProp/Category" href="./Category:Toxine_bactérienne" />
<link rel="mw:PageProp/Category" href="./Category:Toxine_bact%C3%A9rienne" />
<link rel="mw:PageProp/Category" href="Category:Toxine_bact%C3%A9rienne" />
@@ -23092,7 +24322,7 @@ New sol transparent links don't need indent-pre nowiki protection
!! options
parsoid=html2wt
language=de
-!! html
+!! html/parsoid
<link rel="mw:PageProp/redirect" href="./Main_Page">
<!-- this is good --> <link rel="mw:PageProp/Category" href="./Category:Good" />
<!-- this is great --> <link rel="mw:PageProp/Category" href="./Kategorie:Great" />
@@ -23106,7 +24336,7 @@ language=de
New interlanguage links (href variations)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Toxine bactérienne" />
<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Toxine_bactérienne" />
<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Toxine_bact%C3%A9rienne" />
@@ -23253,16 +24483,17 @@ parsoid
<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"alt","ak":"alt="},{"ck":"caption","ak":"bar"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"alt":"","resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"alt":"alt=","resource":"File:Foobar.jpg"}}'/></a><figcaption>bar</figcaption></figure>
!! end
-#!! test
-#Image: new attributes should be serialized in wiki's language for RTL languages (bug 51852)
-#!! options
-#parsoid=html2wt
-#language=ar
-#!! html
-#<figure class="mw-default-size mw-halign-right" typeof="mw:Image/Thumb"><a href="Imagen:Foobar.jpg"><img resource="./Imagen:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="20" width="180"/></a></figure>
-#!! wikitext
-#[[Imagen:Foobar.jpg|derecha|miniaturadeimagen]]
-#!! end
+!! test
+Image: new attributes should be serialized in wiki's language for RTL languages (bug 51852)
+!! options
+parsoid=html2wt
+language=ar
+disabled
+!! html/parsoid
+<figure class="mw-default-size mw-halign-right" typeof="mw:Image/Thumb"><a href="./Imagen:Foobar.jpg"><img resource="./Imagen:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="20" width="180"/></a></figure>
+!! wikitext
+[[Imagen:Foobar.jpg|derecha|miniaturadeimagen]]
+!! end
!! test
Image: Block level image should have \n before and after
@@ -23272,7 +24503,7 @@ Image: Block level image should have \n before and after
456
!! html/parsoid
<p>123</p>
-<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150"/></a></figure>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150"/></a></figure>
<p>456</p>
!!end
@@ -23290,26 +24521,22 @@ Image: New block level image should have \n before and after (existing content)
!! test
Image: upright option (parsoid)
-!! options
-parsoid
!! wikitext
[[File:Foobar.jpg|thumb|upright|caption]]
[[File:Foobar.jpg|thumb|upright=0.5|caption]]
[[File:Foobar.jpg|thumb|500x500px|upright=0.5|caption]]
-!! html
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="19" width="170"/></a><figcaption>caption</figcaption></figure>
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="12" width="110"/></a><figcaption>caption</figcaption></figure>
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="57" width="500"/></a><figcaption>caption</figcaption></figure>
+!! html/parsoid
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/170px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="19" width="170"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/110px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="12" width="110"/></a><figcaption>caption</figcaption></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/500px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="57" width="500"/></a><figcaption>caption</figcaption></figure>
!!end
!! test
Image: upright option is ignored on inline and frame images (parsoid)
-!! options
-parsoid
!! wikitext
[[File:Foobar.jpg|500x500px|upright=0.5|caption]]
-!! html
-<p><span typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="57" width="500"/></a></span></p>
+!! html/parsoid
+<p><span typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/500px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="57" width="500"/></a></span></p>
!!end
!! test
@@ -23358,7 +24585,7 @@ parsoid=html2wt
Lists: Serialize correctly even when list content is wrapped in p-tags (like VE does)
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<ul>
<li><p>foo</p></li>
</ul>
@@ -23370,7 +24597,7 @@ parsoid=html2wt
Lists: Serialize correctly even when list tags has unneeded whitespace between tags
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<ul> <li>foo</li></ul>
!! wikitext
* foo
@@ -23380,7 +24607,7 @@ parsoid=html2wt
Don't strip leading whitespace when handling indent-pre suppressing tags
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<table>
<tr><td> indented row</td></tr>
</table>
@@ -23413,55 +24640,39 @@ foo
Nowiki-wrap leading whitespace when handling indent-pre inducing tags
!! options
parsoid=html2wt
-!! wikitext
-foo
-<nowiki> </nowiki><span>bar</span>
+!! html/parsoid
+<p>foo</p>
+ <span>bar</span>
<span>foo2
-<nowiki> </nowiki></span>bar2
+ </span>bar2
<div>foo</div>
-<nowiki> </nowiki><span>bar</span>
+ <span>bar</span>
<div>
-<nowiki> </nowiki><span>foo</span>
+ <span>foo</span>
</div>
-!! html
-<p>foo</p>
- <span>bar</span>
+!! wikitext
+foo
+<nowiki> </nowiki><span>bar</span>
<span>foo2
- </span>bar2
+<nowiki> </nowiki></span>bar2
<div>foo</div>
- <span>bar</span>
+<nowiki> </nowiki><span>bar</span>
<div>
- <span>foo</span>
+<nowiki> </nowiki><span>foo</span>
</div>
!! end
!! test
-Lists: Add space after bullets
-!! options
-parsoid=html2wt
-!! html
-<ul>
-<li>foo</li>
-<li> bar</li>
-<li><span> baz</span></li>
-</ul>
-!! wikitext
-* foo
-* bar
-* <span> baz</span>
-!! end
-
-!! test
Lists: Dont insert newlines in a serialized list item.
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<ul><li>a<br>b</li><li>c</li></ul>
!! wikitext
* a<br>b
@@ -23469,49 +24680,106 @@ parsoid=html2wt
!! end
!! test
-Headings: Add space before/after == (Bug 51744)
+1. Headings: Force sol-transparent links and behavior switches to serialize before/after
!! options
-parsoid=html2wt
-!! html
-<h2>foo</h2>
-<h2> bar</h2>
-<h2>baz </h2>
-<h2><span> baz</span></h2>
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": false
+}
+!! html/parsoid
+<h2>hello there<link href="./Category:A1" rel="mw:PageProp/Category" /></h2>
+<h2><link href="./Category:A2" rel="mw:PageProp/Category" />hi pal</h2>
+
+<h2><!--foo--> <link href="./Category:A3" rel="mw:PageProp/Category" /> how goes it</h2>
+<h2>it goes well <link href="./Category:A4" rel="mw:PageProp/Category" /> <!--bar--></h2>
+
+<h2 data-parsoid='{}'>howdy<link href="./Category:A5" rel="mw:PageProp/Category" /></h2>
+
+<h2><meta property="mw:PageProp/toc" /> ok</h2>
!! wikitext
-== foo ==
+== hello there [[Category:A1]] ==
-== bar ==
+== [[Category:A2]] hi pal ==
-== baz ==
+== <!--foo--> [[Category:A3]] how goes it ==
-== <span> baz</span> ==
+== it goes well [[Category:A4]] <!--bar--> ==
+
+==howdy [[Category:A5]] ==
+
+== __TOC__ ok ==
!! end
!! test
-Headings: Force metas to serialize before/after
+2. Headings: Force sol-transparent links and behavior switches to serialize before/after
!! options
-parsoid=html2wt
-!! html
-<h2>hello there<link href="Category:A1" rel="mw:PageProp/Category" /></h2>
-<h2><link href="Category:A2" rel="mw:PageProp/Category" />hi pal</h2>
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<h2>hello there<link href="./Category:A1" rel="mw:PageProp/Category" /></h2>
+<h2><link href="./Category:A2" rel="mw:PageProp/Category" />hi pal</h2>
-<h2><!--foo--> <link href="Category:A3" rel="mw:PageProp/Category" /> how goes it</h2>
+<h2><!--foo--> <link href="./Category:A3" rel="mw:PageProp/Category" /> how goes it</h2>
+<h2>it goes well <link href="./Category:A4" rel="mw:PageProp/Category" /> <!--bar--></h2>
+
+<h2><meta property="mw:PageProp/toc" /> ok</h2>
!! wikitext
== hello there ==
[[Category:A1]]
-
[[Category:A2]]
+
== hi pal ==
<!--foo--> [[Category:A3]]
+
== how goes it ==
+
+== it goes well ==
+[[Category:A4]] <!--bar-->
+
+__TOC__
+
+== ok ==
+!! end
+
+!! test
+Headings: Don't hoist metas that come from templates
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<h2><span about="#mwt1" typeof="mw:Transclusion" data-parsoid="{}" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo [[Category:Foo]]"}},"i":0}}]}'>foo </span><link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" data-parsoid="{}" /></h2>
+!! wikitext
+== {{echo|foo [[Category:Foo]]}} ==
+!! end
+
+!! test
+Headings: Category in ref isn't hoisted
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<h2> foo <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> </h2>
+
+<ol class="references" typeof="mw:Extension/references" about="#mwt3" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">bar <link rel="mw:PageProp/Category" href="./Category:Baz" /> </span></li></ol>
+!! wikitext
+== foo <ref>bar
+[[Category:Baz]] </ref> ==
+
+<references />
!! end
!! test
Parsoid: Serialize positional parameters with = in them as named parameter
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p about="#mwt1" typeof="mw:Transclusion"
data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"f=oo"}},"i":0}}]}'>foo</p>
@@ -23535,7 +24803,7 @@ data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},
Parsoid: Serialize positional parameters with = in extlink as named parameter
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p><a rel="mw:ExtLink" href="http://stuff?is=ok" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"http://stuff?is=ok"}},"i":0}}]}'>http://stuff?is=ok</a></p>
!! wikitext
{{echo|1 = http://stuff?is=ok}}
@@ -23545,7 +24813,7 @@ parsoid=html2wt
Parsoid: Correctly serialize block-node children when they are a combination of text and p-nodes
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<div>a<p>b</p></div>
<div>a
<p>b</p></div>
@@ -23570,7 +24838,7 @@ b
Substrings resembling wikitext in hrefs should not get nowiki escapes
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<a rel="mw:WikiLink" href="./Foo''bar''baz">Foo''bar''baz</a>
!! wikitext
[[Foo''bar''baz]]
@@ -23580,27 +24848,89 @@ parsoid=html2wt
Enforce single-line context in the serializer
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<h2>testing
123</h2>
+<h2> hi <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"bogus","href":"./Template:Bogus"},"params":{"1":{"wt":"there\nyou"}},"i":0}}]}'>there</span><span about="#mwt1">
+</span><span about="#mwt1">you</span> </h2>
+
+<h2> foo <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span> </h2>
+
+<ol class="references" typeof="mw:Extension/references" about="#mwt3" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1">↑</a></span> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">hello
+there</span></li></ol>
+
<ul><li>asd
sdf</li></ul>
+
+<ul><li>foo
+bar
+baz</li>
+<li>foo <b>bar</b>
+baz</li></ul>
+
+<dl><dt>hi
+ho </dt><dd data-parsoid='{"stx":"row"}'> hi
+ho</dd></dl>
+
+<dl><dd> <table>
+<tbody><tr><td> ha
+ha
+ha</td></tr>
+</tbody></table></dd></dl>
!! wikitext
== testing 123 ==
+== hi {{bogus|there
+you}} ==
+
+== foo <ref>hello
+there</ref> ==
+
+<references />
+
* asd sdf
+
+* foo bar baz
+* foo '''bar''' baz
+
+; hi ho : hi ho
+
+: {|
+| ha
+ha
+ha
+|}
+!! end
+
+!! test
+Serialize new placeholder space without spans
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>foo<span typeof="mw:Placeholder"> </span>: bar</p>
+
+<p>foo<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span>: bar</p>
+
+<span typeof="mw:Extension/ref" data-mw="{&quot;name&quot;:&quot;ref&quot;,&quot;body&quot;:{&quot;html&quot;:&quot;foo<span typeof=\&quot;mw:Placeholder\&quot;>&amp;nbsp;</span>: bar&quot;}}"><sup>[1]</sup></span>ok</p>
+!! wikitext
+foo : bar
+
+foo : bar
+
+<ref>foo : bar</ref>ok
!! end
-#-----------------------------
-# I/B quote minimization tests
-#-----------------------------
+
+#-----------------------
+# Tag minimization tests
+#-----------------------
!! test
1. I/B quote minimization: wikitext-only tags should be combined
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p><i>A</i><i>B</i></p>
<p><b>A</b><b>B</b></p>
<p><i>A</i><b><i>B</i></b></p>
@@ -23631,7 +24961,7 @@ parsoid=html2wt
2. I/B quote minimization: wikitext and html tags should not be combined
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p><i>A</i><i data-parsoid='{"stx":"html"}'>B</i></p>
<p><i>A</i><b><i data-parsoid='{"stx":"html"}'>B</i></b></p>
!! wikitext
@@ -23644,7 +24974,7 @@ parsoid=html2wt
3. I/B quote minimization: templated content stops minimization
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p><i>A</i><i about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&#39;&#39;B&#39;&#39;"}},"i":0}}]}'>B</i>
<p><i>A</i><b about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&#39;&#39;&#39;&#39;&#39;B&#39;&#39;&#39;&#39;&#39;"}},"i":0}}]}'><i>B</i></b>
!! wikitext
@@ -23657,7 +24987,7 @@ parsoid=html2wt
4. I/B quote minimization: new content should be mimimized with adjacent old content
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<p><i>A</i><i>B</i></p>
<p><b>A</b><b>B</b></p>
<p><i>A</i><b><i>B</i></b></p>
@@ -23699,18 +25029,61 @@ parsoid={
''ac''
!! end
-#------------------------------------
-# End of I/B quote minimization tests
-#------------------------------------
+!! test
+1. Merge adjacent link nodes as long as at least one element is new
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Football">Foot</a><a rel="mw:WikiLink" href="./Football">ball</a>
+<a data-parsoid="{}" rel="mw:WikiLink" href="./Football">Foot</a><a rel="mw:WikiLink" href="./Football">ball</a>
+<a data-parsoid="{}" rel="mw:WikiLink" href="./Football">Foot</a><a data-parsoid="{}" rel="mw:WikiLink" href="./Football">ball</a>
+!! wikitext
+[[Football]]
+[[Football]]
+[[Football|Foot]][[Football|ball]]
+!! end
+
+!! test
+2. Merge adjacent link nodes and enable additional normalizations
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Football"><i>Foot</i></a><a rel="mw:WikiLink" href="./Football"><i>ball</i></a>
+!! wikitext
+[[Football|''Football'']]
+!! end
+
+!! test
+3. Don't merge adjacent link nodes if scrubWikitext is false
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": false
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Football">Foot</a><a rel="mw:WikiLink" href="./Football">ball</a>
+!! wikitext
+[[Football|Foot]][[Football|ball]]
+!! end
+
+#------------------------------
+# End of tag minimization tests
+#------------------------------
!!test
Bug 54262: New entities
!! options
parsoid=html2wt
+!! html/parsoid
+<span typeof="mw:Entity">&nbsp;</span>
!! wikitext
&nbsp;
-!! html
-<span typeof="mw:Entity">&nbsp;</span>
!! end
## Note that there is no wikitext output for 'unknownproperty' ##
@@ -23720,7 +25093,7 @@ parsoid=html2wt
Magic words
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<meta property='mw:PageProp/toc' />
<meta property='mw:PageProp/notoc' />
<meta property='mw:PageProp/forcetoc' />
@@ -23747,7 +25120,7 @@ __NOCONTENTCONVERT__
Consecutive <pre>s should not get merged
!! options
parsoid=html2wt,html2html
-!! html
+!! html/parsoid
<pre>a</pre><pre>b</pre>
<pre>c
@@ -23779,8 +25152,8 @@ f</pre>
Edited ISBN links not serializable as ISBN links should serialize as wikilinks
!! options
parsoid=html2wt
-!! html
-<a rel="mw:ExtLink" href="./Special:BookSources/1234567890">ISBN 1234567895</a>
+!! html/parsoid
+<a href="./Special:BookSources/1234567890" rel="mw:ExtLink">ISBN 1234567895</a>
!! wikitext
[[Special:BookSources/1234567890|ISBN 1234567895]]
!! end
@@ -23789,7 +25162,7 @@ parsoid=html2wt
Edited RFC links not serializable as RFC links should serialize as extlinks
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<a href="//tools.ietf.org/html/rfc123" rel="mw:ExtLink">New RFC</a>
!! wikitext
[//tools.ietf.org/html/rfc123 New RFC]
@@ -23799,7 +25172,7 @@ parsoid=html2wt
Edited PMID links not serializable as PMID links should serialize as extlinks
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<a href="//www.ncbi.nlm.nih.gov/pubmed/123?dopt=Abstract" rel="mw:ExtLink">New PMID</a>
!! wikitext
[//www.ncbi.nlm.nih.gov/pubmed/123?dopt=Abstract New PMID]
@@ -23856,10 +25229,131 @@ x<nowiki/>http://cscott.net<nowiki/>x
!! end
!! test
+WTS of edited autolink-like text (T103364)
+!! options
+parsoid={
+ "modes": ["wt2wt"],
+ "changes": [
+ [ "span[typeof]", "removeAttr", "typeof" ]
+ ]
+}
+!! wikitext
+Not a link: <nowiki>http://example.com</nowiki>.
+!! wikitext/edited
+Not a link: <span><nowiki>http://example.com</nowiki></span>.
+!! end
+
+!! test
+WTS of newly-authored autolink-like text (T103364)
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>http://example.com is not a link.</p>
+!! wikitext
+<nowiki>http://example.com is not a link.</nowiki>
+!! end
+
+!! test
+WTS of autolink-like text after an autolink (T108563)
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://example.com">http://example.com</a> http://example.com is not a link.</p>
+!! wikitext
+http://example.com<nowiki> http://example.com is not a link.</nowiki>
+!! end
+
+!! test
+Magic links inside links (not autolinked)
+!! wikitext
+[[Foo|http://example.com]]
+[[Foo|RFC 1234]]
+[[Foo|PMID 1234]]
+[[Foo|ISBN 123456789x]]
+
+[http://foo.com http://example.com]
+[http://foo.com RFC 1234]
+[http://foo.com PMID 1234]
+[http://foo.com ISBN 123456789x]
+!! html+tidy
+<p><a href="/wiki/Foo" title="Foo">http://example.com</a> <a href="/wiki/Foo" title="Foo">RFC 1234</a> <a href="/wiki/Foo" title="Foo">PMID 1234</a> <a href="/wiki/Foo" title="Foo">ISBN 123456789x</a></p>
+<p><a rel="nofollow" class="external text" href="http://foo.com">http://example.com</a> <a rel="nofollow" class="external text" href="http://foo.com">RFC 1234</a> <a rel="nofollow" class="external text" href="http://foo.com">PMID 1234</a> <a rel="nofollow" class="external text" href="http://foo.com">ISBN 123456789x</a></p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo">http://example.com</a>
+<a rel="mw:WikiLink" href="./Foo" title="Foo">RFC 1234</a>
+<a rel="mw:WikiLink" href="./Foo" title="Foo">PMID 1234</a>
+<a rel="mw:WikiLink" href="./Foo" title="Foo">ISBN 123456789x</a></p>
+
+<p><a rel="mw:ExtLink" href="http://foo.com">http://example.com</a>
+<a rel="mw:ExtLink" href="http://foo.com">RFC 1234</a>
+<a rel="mw:ExtLink" href="http://foo.com">PMID 1234</a>
+<a rel="mw:ExtLink" href="http://foo.com">ISBN 123456789x</a></p>
+!! end
+
+!! test
+Magic links inside image captions (autolinked)
+!! wikitext
+[[File:Foobar.jpg|thumb|http://example.com]]
+[[File:Foobar.jpg|thumb|RFC 1234]]
+[[File:Foobar.jpg|thumb|PMID 1234]]
+[[File:Foobar.jpg|thumb|ISBN 123456789x]]
+!! html+tidy
+<div class="thumb tright">
+<div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div>
+</div>
+</div>
+<div class="thumb tright">
+<div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>
+<a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc1234">RFC 1234</a></div>
+</div>
+</div>
+<div class="thumb tright">
+<div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>
+<a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a></div>
+</div>
+</div>
+<div class="thumb tright">
+<div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>
+<a href="/wiki/Special:BookSources/123456789X" class="internal mw-magiclink-isbn">ISBN 123456789x</a></div>
+</div>
+</div>
+!! html/parsoid
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" href="http://example.com">http://example.com</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="//tools.ietf.org/html/rfc1234" rel="mw:ExtLink">RFC 1234</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink">PMID 1234</a></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="./Special:BookSources/123456789X" rel="mw:WikiLink">ISBN 123456789x</a></figcaption></figure>
+!! end
+
+!! test
+WTS of magic word text (T109371)
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p>RFC 1234</p>
+<p><a href="http://foo.com" rel="mw:ExtLink">RFC 1234</a></p>
+<p><a href="./Foo" rel="mw:WikiLink">RFC 1234</a></p>
+!! wikitext
+<nowiki>RFC 1234</nowiki>
+
+[http://foo.com RFC 1234]
+
+[[Foo|RFC 1234]]
+!! end
+
+!! test
Edited Redirect link should emit a non-piped wikitext link
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<link rel="mw:PageProp/redirect" href="Bar" data-parsoid='{"a":{"href":"./Foo"},"sa":{"href":"Foo"}}'>
!! wikitext
#REDIRECT [[Bar]]
@@ -23869,7 +25363,7 @@ parsoid=html2wt
T75121: Infer extension name from typeOf if data-mw is not present
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<div typeOf="mw:Extension/foo"></div>
!! wikitext
<foo />
@@ -23929,7 +25423,7 @@ parsoid=html2wt,wt2wt
HTML id attribute with Parsoid-like element ids should not be serialized to wikitext
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<table id='mwAb'>
<td id='mwAc'>foo</td>
<td id='serialize-this'>bar</td>
@@ -23945,7 +25439,7 @@ parsoid=html2wt
Parsoid-like element ids should not be serialized to wikitext unless shadowed
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<div id="mwAQ" data-parsoid='{"stx":"html","a":{"id":"mwAQ"},"sa":{"id":"hello"}}'>ok</div>
!! wikitext
<div id="hello">ok</div>
@@ -23972,12 +25466,608 @@ parsoid={
Never serialize a-tag as html, regardless of what data-parsoid has to say
!! options
parsoid=html2wt
-!! html
+!! html/parsoid
<a rel="mw:WikiLink" href="./Foo" title="Foo" data-parsoid='{"stx":"html"}'>Foo</a>
!! wikitext
[[Foo]]
!! end
+## SSS FIXME: This is broken output nevertheless.
+## What might be a reasonable non-broken output for this?
+## This is an edge case unlikely to be seen in production
+## that I am not wasting more time on this right now.
+!! test
+Never serialize a-tag as html, no matter what attributes it has
+!! options
+parsoid=html2wt
+!! html/parsoid
+<a bad='true' href='http://boo.org'><img src='http://boohoo.org' /></a>
+!! wikitext
+[http://boo.org http://boohoo.org]
+!! end
+
+# Misnested is an indication that selser can reuse the source but these have
+# shown to sneak through on occasion. See T101768.
+# The original wikitext here is: [http://test.com [[one]] two three]
+!! test
+Strip span tags added to mark as misnested
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p data-parsoid='{}'><a rel="mw:ExtLink" href="http://test.com" data-parsoid='{"targetOff":17,"contentOffsets":[17,34]}'></a><a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"simple","a":{"href":"./One"},"sa":{"href":"one"},"misnested":true}'>one</a><span data-parsoid='{"misnested":true}'> two three</span></p>
+!! wikitext
+[http://test.com][[one]] two three
+!! end
+
+# --------------------------------------------
+# Tests spec'ing wikitext serialization norms |
+# --------------------------------------------
+
+!! test
+Lists: Add space after bullets
+!! options
+parsoid=html2wt
+!! html/parsoid
+<ul>
+<li>foo</li>
+<li> bar</li>
+<li><span> baz</span></li>
+</ul>
+!! wikitext
+* foo
+* bar
+* <span> baz</span>
+!! end
+
+!! test
+1. Headings: Add space before/after == (T53744)
+!! options
+parsoid=html2wt
+!! html/parsoid
+<h2>foo</h2>
+<h2> bar</h2>
+<h2>baz </h2>
+<h2><span> baz</span></h2>
+!! wikitext
+== foo ==
+
+== bar ==
+
+== baz ==
+
+== <span> baz</span> ==
+!! end
+
+!! test
+2. Headings: Add space before/after == even after hoisted content
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<h2> <link href="./Category:A2" rel="mw:PageProp/Category" />ok</h2>
+!! wikitext
+ [[Category:A2]]
+
+== ok ==
+!! end
+
+!! test
+1. Headings: suppress newly created empty headings
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<h2></h2>
+!! wikitext
+!! end
+
+!! test
+2. Headings: don't suppress empty headings if scrubWikitext is false
+!! options
+parsoid=html2wt
+!! html/parsoid
+<h2></h2>
+!! wikitext
+==<nowiki/>==
+!! end
+
+!! test
+3. Headings: suppress empty headings on edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "#x", "remove"]
+ ]
+}
+!! wikitext
+==<span id="x">foo</span>==
+!! wikitext/edited
+!! end
+
+!! test
+1. WT Quote Tags: suppress newly created empty style tags
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<i></i><b></b>
+!! wikitext
+!! end
+
+!! test
+2. WT Quote Tags: don't suppress empty style tags if scrubWikitext is false
+!! options
+parsoid=html2wt
+!! html/parsoid
+<i></i><b></b>
+!! wikitext
+''<nowiki/>'''''<nowiki/>'''
+!! end
+
+!! test
+3. WT Quote Tags: suppress empty style tags on edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "#x", "remove"]
+ ]
+}
+!! wikitext
+'''<span id="x">foo</span>'''
+!! wikitext/edited
+!! end
+
+!! test
+1. Anchors: suppress newly created empty anchors
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Test" title="Test"></a>
+!! wikitext
+!! end
+
+!! test
+2. Anchors: don't suppress empty anchors if scrubWikitext is false
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": false
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Test" title="Test"></a>
+!! wikitext
+[[Test|<nowiki/>]]
+!! end
+
+!! test
+3. Anchors: suppress empty anchors on edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "#x", "remove"]
+ ]
+}
+!! wikitext
+[[Test|<span id="x">foo</span>]]
+!! wikitext/edited
+!! end
+
+!! test
+3a. Anchors: do not suppress numbered extlinks
+!! options
+parsoid={
+ "modes": ["wt2wt"],
+ "scrubWikitext": true
+}
+!! wikitext
+[http://foo.com]
+!! html/parsoid
+<a rel="mw:ExtLink" href="http://foo.com"></a>
+!! end
+
+!! test
+3b. Anchors: do not suppress numbered extlinks
+!! options
+parsoid={
+ "modes": ["wt2wt"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "#x", "remove"]
+ ]
+}
+!! wikitext
+[http://foo.com <span id="x">foo</span>]
+!! wikitext/edited
+[http://foo.com]
+!! end
+
+!!test
+Normalizations should be restricted to edited content
+!!options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "h1", "before", "<i></i>"]
+ ]
+}
+!!wikitext
+a
+= =
+b
+!!wikitext/edited
+a
+= =
+b
+!!end
+
+!! test
+1. Multiple normalizations (html2wt)
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html
+<h2><i></i></h2>
+<p><a href='Foo' rel='mw:WikiLink'>foo<i></i>
+ </a><b><i></i></b>x</p>
+!! wikitext
+
+[[foo]]
+x
+
+!! end
+
+!! test
+2. Multiple normalizations (selser)
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "#x", "after", "<h1><i></i></h1>\n<p> x<b></b></p>"]
+ ]
+}
+!! wikitext
+<span id="x">foo</span>
+!! wikitext/edited
+<span id="x">foo</span>
+
+x
+!! end
+
+!! test
+1. Indent Pre Nowiki: suppress whitespace at the start of new paragraph
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<p> hi</p>
+<p> hello</p>
+!! wikitext
+hi
+
+hello
+!! end
+
+!! test
+2. Indent Pre Nowiki: don't suppress whitespace at the start of new paragraph if scrubWikitext is false
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p> hi</p>
+<p> hello</p>
+!! wikitext
+<nowiki> </nowiki>hi
+
+<nowiki> </nowiki> hello
+!! end
+
+!! test
+3. Indent Pre Nowiki: suppress whitespace after newlines in new paragraph or table cell
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<p>Foo
+ bar
+baz</p>
+
+<table><tr><td>Foo
+ bar
+ baz bang</td></tr></table>
+
+<p><!--boo--> foo
+ bar</p>
+
+<p> foo
+ bar<span>boo</span></p>
+!! wikitext
+Foo
+bar
+baz
+
+{|
+|Foo
+bar
+baz bang
+|}
+
+<!--boo-->foo
+bar
+
+foo
+bar<span>boo</span>
+!! end
+
+!! test
+4. Indent Pre Nowiki: suppress leading whitespace in edited paragraphs
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "p", "html", " a\n b" ]
+ ]
+}
+!! wikitext
+xyz
+!! wikitext/edited
+a
+b
+!! end
+
+!! test
+1. New links that end in spaces
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": false
+}
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./Berlin" title="Berlin">Berlin </a>is the capital of Germany.</p>
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo">Foo </a><b>bar</b></p>
+<p><a rel="mw:WikiLink" href="./Boston" title="Boston">Boston </a> is a city.</p>
+!! wikitext
+[[Berlin ]]<nowiki/>is the capital of Germany.
+
+[[Foo ]]'''bar'''
+
+[[Boston ]] is a city.
+!! end
+
+!! test
+2. New links that end in spaces
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./Berlin" title="Berlin">Berlin </a>is the capital of Germany.</p>
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo">Foo </a><b>bar</b></p>
+<p><a rel="mw:WikiLink" href="./Boston" title="Boston">Boston </a> is a city.</p>
+!! wikitext
+[[Berlin]] is the capital of Germany.
+
+[[Foo]] '''bar'''
+
+[[Boston]] is a city.
+!! end
+
+!! test
+1. Table cells with escapable prefixes
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": false
+}
+!! html
+<table>
+<tr><td>a</td></tr>
+<tr><td>-</td></tr>
+<tr><td>+</td></tr>
+</table>
+!! wikitext
+{|
+|a
+|-
+|<nowiki>-</nowiki>
+|-
+|<nowiki>+</nowiki>
+|}
+!! end
+
+!! test
+2. Table cells with escapable prefixes
+!! options
+parsoid={
+ "modes": ["html2wt"],
+ "scrubWikitext": true
+}
+!! html
+<table>
+<tr><td>a</td></tr>
+<tr><td>-</td></tr>
+<tr><td>+</td></tr>
+</table>
+!! wikitext
+{|
+|a
+|-
+| -
+|-
+| +
+|}
+!! end
+
+!! test
+3a. Table cells with escapable prefixes after edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "table tbody tr:first-child td:first-child", "remove"]
+ ]
+}
+!! wikitext
+{|
+|a||-
+|}
+!! wikitext/edited
+{|
+| -
+|}
+!! end
+
+!! test
+3b. Table cells with escapable prefixes after edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "table tbody tr:first-child td:first-child", "html", "-" ],
+ [ "#x", "remove" ]
+ ]
+}
+!! wikitext
+{|
+|pqr
+|<span id="x">foo</span>+
+|}
+!! wikitext/edited
+{|
+| -
+| +
+|}
+!! end
+
+# FIXME: This test will fail because
+# normalization doesn't realize that the id attribute
+# will eliminate the escapable scenario
+!! test
+4a. Table cells without escapable prefixes after edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "#x", "html", "-" ]
+ ]
+}
+!! wikitext
+{|
+| id="x" |abcd
+|}
+!! wikitext/edited
+{|
+| id="x" |-
+|}
+!! end
+
+## This tests normalizer's ability to discriminate between
+## cells having identical content.
+!! test
+4b. Table cells without escapable prefixes after edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "td", "html", "-" ]
+ ]
+}
+!! wikitext
+{|
+|a||b
+|}
+!! wikitext/edited
+{|
+| -||-
+|}
+!! end
+
+## This tests normalizer's ability to not be tripped by
+## comments (and whitespace)
+!! test
+4c. Table cells without escapable prefixes after edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "table tbody tr td:first-child", "remove" ]
+ ]
+}
+!! wikitext
+{|
+|-
+<!--foo--> |a||-
+|}
+!! wikitext/edited
+{|
+|-
+<!--foo--> | -
+|}
+!! end
+
+## This tests normalizer's ability to handle HTML cells
+!! test
+4d. Table cells without escapable prefixes after edits
+!! options
+parsoid={
+ "modes": ["selser"],
+ "scrubWikitext": true,
+ "changes": [
+ [ "td", "html", "-" ]
+ ]
+}
+!! wikitext
+<table>
+<tr><td>a</td></tr>
+</table>
+!! wikitext/edited
+<table>
+<tr><td>-</td></tr>
+</table>
+!! end
+
+!! test
+Escape nowiki DOM elements
+!! options
+parsoid=html2wt
+!! html/parsoid
+<nowiki><i>foo</i></nowiki>
+!! wikitext
+&lt;nowiki&gt;''foo''&lt;/nowiki&gt;
+!! end
+
+# ---------------------------------------------------
+# End of tests spec'ing wikitext serialization norms |
+# ---------------------------------------------------
+
# -----------------------------------------------------------------
# End of section for Parsoid-only html2wt tests for serialization
# of new content
@@ -23993,7 +26083,7 @@ parsoid=html2wt
## T90517
!! test
-1. Selser: New comments should not be lost
+Selser: New comments should not be lost
!! options
parsoid={
"modes": ["selser"],
@@ -24014,7 +26104,7 @@ parsoid={
## T89383
!! test
-2. Selser: Check for validity of DSR before using it
+Selser: Check for validity of DSR before using it
!! options
parsoid={
"modes": ["selser"],
@@ -24029,10 +26119,55 @@ parsoid={
<span id="a">a</span>
!! end
+!! test
+1. DOMDiff: Changes to <ref> content should be looked up using id
+!! options
+parsoid={
+ "modes": ["selser"],
+ "changes": [
+ ["#X", "after", "bar"],
+ ["#Y", "after", "baz"]
+ ]
+}
+!! wikitext
+X <ref><span id="X">foo</span></ref>
+Y <ref name="a" />
+<references>
+<ref name="a"><span id="Y">foo</span></ref>
+</references>
+!! wikitext/edited
+X <ref><span id="X">foo</span>bar</ref>
+Y <ref name="a" />
+<references>
+<ref name="a"><span id="Y">foo</span>baz</ref>
+</references>
+!! end
+
+!! test
+2. DOMDiff: Changes to <ref> content should be looked up using id
+!! options
+parsoid={
+ "modes": ["selser"],
+ "changes": [
+ ["#Z", "after", "bar"]
+ ]
+}
+!! wikitext
+A <ref>foo bar for a</ref>
+B <ref group="X" name="b" />
+
+<references />
+
+<references group="X">
+<ref name="b"><span id="Z">foo</span></ref>
+</references>
+!! wikitext/edited
+A <ref>foo bar for a</ref>
+B <ref group="X" name="b" />
-TODO:
-more images
-more tables
-character entities
-and much more
-Try for 100% code coverage
+<references />
+
+<references group="X">
+<ref name="b"><span id="Z">foo</span>bar</ref>
+</references>
+!! end
diff --git a/tests/parser/preprocess/All_system_messages.expected b/tests/parser/preprocess/All_system_messages.expected
index 3665e3c1..57223da6 100644
--- a/tests/parser/preprocess/All_system_messages.expected
+++ b/tests/parser/preprocess/All_system_messages.expected
@@ -1370,12 +1370,12 @@ Message
&lt;/td&gt;&lt;td&gt;
<template lineStart="1"><title>int:Emailmessage</title></template>
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
-[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpage&amp;action=edit emailpage]&lt;br&gt;
-[[MediaWiki_talk:Emailpage|Talk]]
+[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailuser&amp;action=edit emailuser]&lt;br&gt;
+[[MediaWiki_talk:Emailuser|Talk]]
&lt;/td&gt;&lt;td&gt;
E-mail user
&lt;/td&gt;&lt;td&gt;
-<template lineStart="1"><title>int:Emailpage</title></template>
+<template lineStart="1"><title>int:Emailuser</title></template>
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpagetext&amp;action=edit emailpagetext]&lt;br&gt;
[[MediaWiki_talk:Emailpagetext|Talk]]
diff --git a/tests/parser/preprocess/All_system_messages.txt b/tests/parser/preprocess/All_system_messages.txt
index c619df7b..cdc223a9 100644
--- a/tests/parser/preprocess/All_system_messages.txt
+++ b/tests/parser/preprocess/All_system_messages.txt
@@ -1370,12 +1370,12 @@ Message
</td><td>
{{int:Emailmessage}}
</td></tr><tr><td>
-[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpage&action=edit emailpage]<br>
-[[MediaWiki_talk:Emailpage|Talk]]
+[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailuser&action=edit emailuser]<br>
+[[MediaWiki_talk:Emailuser|Talk]]
</td><td>
E-mail user
</td><td>
-{{int:Emailpage}}
+{{int:Emailuser}}
</td></tr><tr><td>
[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpagetext&action=edit emailpagetext]<br>
[[MediaWiki_talk:Emailpagetext|Talk]]
diff --git a/tests/parserTests.php b/tests/parserTests.php
index 5d21319b..4d84025b 100644
--- a/tests/parserTests.php
+++ b/tests/parserTests.php
@@ -80,7 +80,7 @@ if ( isset( $options['file'] ) ) {
}
# Print out software version to assist with locating regressions
-$version = SpecialVersion::getVersion();
+$version = SpecialVersion::getVersion( 'nodb' );
echo "This is MediaWiki version {$version}.\n\n";
if ( isset( $options['fuzz'] ) ) {
diff --git a/tests/phpunit/LessFileCompilationTest.php b/tests/phpunit/LessFileCompilationTest.php
index df4690a4..eec02edc 100644
--- a/tests/phpunit/LessFileCompilationTest.php
+++ b/tests/phpunit/LessFileCompilationTest.php
@@ -45,11 +45,7 @@ class LessFileCompilationTest extends ResourceLoaderTestCase {
$method->setAccessible( true );
$compiler = $method->invoke( $this->module, $rlContext );
- $this->assertNotNull( $compiler->compileFile( $this->file ) );
- }
-
- public function getName( $withDataSet = true ) {
- return $this->toString();
+ $this->assertNotNull( $compiler->parseFile( $this->file )->getCss() );
}
public function toString() {
diff --git a/tests/phpunit/Makefile b/tests/phpunit/Makefile
index a33b86a3..e1537bf5 100644
--- a/tests/phpunit/Makefile
+++ b/tests/phpunit/Makefile
@@ -73,7 +73,6 @@ help:
#
# Targets:
# phpunit (default) Run all the tests with phpunit
- # install Install PHPUnit from phpunit.de
# tap Run the tests individually through Test::Harness's prove(1)
# help You're looking at it!
# coverage Run the tests and generates an HTML code coverage report
diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php
index 72cac051..7dc7027a 100644
--- a/tests/phpunit/MediaWikiTestCase.php
+++ b/tests/phpunit/MediaWikiTestCase.php
@@ -204,13 +204,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
while ( $this->db->trxLevel() > 0 ) {
$this->db->rollback();
}
-
- // don't ignore DB errors
- $this->db->ignoreErrors( false );
}
DeferredUpdates::clearPendingUpdates();
+ ob_start( 'MediaWikiTestCase::wfResetOutputBuffersBarrier' );
}
protected function addTmpFiles( $files ) {
@@ -218,6 +216,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
}
protected function tearDown() {
+ $status = ob_get_status();
+ if ( isset( $status['name'] ) && $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier' ) {
+ ob_end_flush();
+ }
+
$this->called['tearDown'] = true;
// Cleaning up temporary files
foreach ( $this->tmpFiles as $fileName ) {
@@ -233,9 +236,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
while ( $this->db->trxLevel() > 0 ) {
$this->db->rollback();
}
-
- // don't ignore DB errors
- $this->db->ignoreErrors( false );
}
// Restore mw globals
@@ -716,9 +716,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
* @param string $function
*/
public function hideDeprecated( $function ) {
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
wfDeprecated( $function );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
}
/**
@@ -1002,9 +1002,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
# This check may also protect against code injection in
# case of broken installations.
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( !$haveDiff3 ) {
$this->markTestSkipped( "Skip test, since diff3 is not configured" );
@@ -1117,7 +1117,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
// of tidy. In that case however, we can not reliably detect whether a failing validation
// is due to malformed HTML, or caused by tidy not being installed as a command line tool.
// That would cause all HTML assertions to fail on a system that has no tidy installed.
- if ( !$GLOBALS['wgTidyInternal'] ) {
+ if ( !$GLOBALS['wgTidyInternal'] || !MWTidy::isEnabled() ) {
$this->markTestSkipped( 'Tidy extension not installed' );
}
@@ -1180,4 +1180,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
self::assertFalse( self::tagMatch( $matcher, $actual, $isHtml ), $message );
}
+
+ /**
+ * Used as a marker to prevent wfResetOutputBuffers from breaking PHPUnit.
+ * @return string
+ */
+ public static function wfResetOutputBuffersBarrier( $buffer ) {
+ return $buffer;
+ }
}
diff --git a/tests/phpunit/README b/tests/phpunit/README
index 0a32ba17..f555812d 100644
--- a/tests/phpunit/README
+++ b/tests/phpunit/README
@@ -14,16 +14,13 @@ TO RETAIN YOUR DATA.
== Installation ==
-If PHPUnit is not installed, follow the installation instructions in the
-PHPUnit Manual at:
-
- http://www.phpunit.de/manual/current/en/installation.html
+If you used composer to install MediaWiki's dependencies PHPUnit will already be available, unless
+you explicitly specified the --no-dev flag during the install. In this case just run "composer update".
-- or -
-
-On Unix-like operating systems, run:
+Otherwise follow the installation instructions in the
+PHPUnit Manual at:
- make install
+ https://phpunit.de/manual/current/en/installation.html
== Running tests ==
@@ -47,7 +44,7 @@ On Windows-family operating systems, run the 'run-tests.bat' batch file.
=== Writing tests ===
-A guide to writing unit tests for MediaWiki can be found at:
+A guide to writing PHP unit tests for MediaWiki can be found at:
- http://mediawiki.org/wiki/Unit_Testing
+ https://www.mediawiki.org/wiki/Manual:PHP_unit_testing
diff --git a/tests/phpunit/ResourceLoaderTestCase.php b/tests/phpunit/ResourceLoaderTestCase.php
index deecb31e..325b20ee 100644
--- a/tests/phpunit/ResourceLoaderTestCase.php
+++ b/tests/phpunit/ResourceLoaderTestCase.php
@@ -25,27 +25,35 @@ abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
return $ctx;
}
- protected function setUp() {
- parent::setUp();
-
- ResourceLoader::clearCache();
-
- $this->setMwGlobals( array(
+ public static function getSettings() {
+ return array(
// For ResourceLoader::inDebugMode since it doesn't have context
- 'wgResourceLoaderDebug' => true,
+ 'ResourceLoaderDebug' => true,
// Avoid influence from wgInvalidateCacheOnLocalSettingsChange
- 'wgCacheEpoch' => '20140101000000',
+ 'CacheEpoch' => '20140101000000',
// For ResourceLoader::__construct()
- 'wgResourceLoaderSources' => array(),
+ 'ResourceLoaderSources' => array(),
// For wfScript()
- 'wgScriptPath' => '/w',
- 'wgScriptExtension' => '.php',
- 'wgScript' => '/w/index.php',
- 'wgLoadScript' => '/w/load.php',
- ) );
+ 'ScriptPath' => '/w',
+ 'ScriptExtension' => '.php',
+ 'Script' => '/w/index.php',
+ 'LoadScript' => '/w/load.php',
+ );
+ }
+
+ protected function setUp() {
+ parent::setUp();
+
+ ResourceLoader::clearCache();
+
+ $globals = array();
+ foreach ( self::getSettings() as $key => $value ) {
+ $globals['wg' . $key] = $value;
+ }
+ $this->setMwGlobals( $globals );
}
}
@@ -68,14 +76,14 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
}
public function getScript( ResourceLoaderContext $context ) {
- return $this->script;
+ return $this->validateScriptFile( 'input', $this->script );
}
public function getStyles( ResourceLoaderContext $context ) {
return array( '' => $this->styles );
}
- public function getDependencies() {
+ public function getDependencies( ResourceLoaderContext $context = null ) {
return $this->dependencies;
}
@@ -94,6 +102,10 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
public function isRaw() {
return $this->isRaw;
}
+
+ public function enableModuleContentVersion() {
+ return true;
+ }
}
class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {
diff --git a/tests/phpunit/data/css/comments.css b/tests/phpunit/data/css/comments.css
new file mode 100644
index 00000000..744a14c7
--- /dev/null
+++ b/tests/phpunit/data/css/comments.css
@@ -0,0 +1,7 @@
+/* url expressions in comments should be ignored */
+
+.selector { /*@noflip*/ background-image: /*@embed*/ url(not-commented.gif); }
+
+/*
+.selector { background-image: url(commented-out.gif); }
+*/
diff --git a/tests/phpunit/data/helpers/WellProtectedClass.php b/tests/phpunit/data/helpers/WellProtectedClass.php
index 99c7f642..a45cfbbf 100644
--- a/tests/phpunit/data/helpers/WellProtectedClass.php
+++ b/tests/phpunit/data/helpers/WellProtectedClass.php
@@ -1,20 +1,47 @@
<?php
-class WellProtectedClass {
+class WellProtectedParentClass {
+ private $privateParentProperty;
+
+ public function __construct() {
+ $this->privateParentProperty = 9000;
+ }
+
+ private function incrementPrivateParentPropertyValue() {
+ $this->privateParentProperty++;
+ }
+
+ public function getPrivateParentProperty() {
+ return $this->privateParentProperty;
+ }
+}
+
+class WellProtectedClass extends WellProtectedParentClass {
protected $property;
+ private $privateProperty;
public function __construct() {
+ parent::__construct();
$this->property = 1;
+ $this->privateProperty = 42;
}
protected function incrementPropertyValue() {
$this->property++;
}
+ private function incrementPrivatePropertyValue() {
+ $this->privateProperty++;
+ }
+
public function getProperty() {
return $this->property;
}
+ public function getPrivateProperty() {
+ return $this->privateProperty;
+ }
+
protected function whatSecondArg( $a, $b = false ) {
return $b;
}
diff --git a/tests/phpunit/data/import/ImportLinkCacheIntegrationTest.xml b/tests/phpunit/data/import/ImportLinkCacheIntegrationTest.xml
new file mode 100644
index 00000000..8949f406
--- /dev/null
+++ b/tests/phpunit/data/import/ImportLinkCacheIntegrationTest.xml
@@ -0,0 +1,43 @@
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.6/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.6/ http://www.mediawiki.org/xml/export-0.6.xsd" version="0.6" xml:lang="en-gb">
+ <siteinfo>
+ <sitename>MW-19</sitename>
+ <base>http://localhost:8080/w/index.php/Main_Page</base>
+ <generator>MediaWiki 1.19.7</generator>
+ <case>first-letter</case>
+ </siteinfo>
+ <page>
+ <title>Lorem ipsum</title>
+ <ns>0</ns>
+ <id>493</id>
+ <sha1>94lztkh4kgb0mvjr87iyjfq4iv7ltlh</sha1>
+ <revision>
+ <id>1358</id>
+ <timestamp>2014-04-04T22:55:04Z</timestamp>
+ <contributor>
+ <username>Tester</username>
+ <id>1</id>
+ </contributor>
+ <text xml:space="preserve" bytes="979">[[Has text::Lorem ipsum dolor sit amet consectetuer Maecenas adipiscing Pellentesque id sem]]. [[Has page::Elit Aliquam urna interdum]] morbi faucibus id tellus ipsum semper wisi. [[Has page::Platea enim hendrerit]] pellentesque consectetuer scelerisque Sed est felis felis quis. Auctor Proin In dolor id et ipsum vel at vitae ut. Praesent elit convallis Praesent aliquet pellentesque vel dolor pellentesque lacinia vitae. At tortor lacus Sed In interdum pulvinar et.
+
+[[Has number::1001]] [[Has quantity::10.25 km²]] [[Has date::1 Jan 2014]] [[Has Url::http://loremipsum.org/]] [[Has annotation uri::http://loremipsum.org/foaf.rdf]] [[Has email::Lorem@ipsum.org]] [[Has temperature::100 °C]] [[Has boolean::true]]
+
+[[Category:Lorem ipsum]]</text>
+ </revision>
+ </page>
+ <page>
+ <title>Category:Lorem ipsum</title>
+ <ns>14</ns>
+ <id>496</id>
+ <sha1>sir97j6uzt9ev2uyhaz1aj4i3spogih</sha1>
+ <revision>
+ <id>1355</id>
+ <timestamp>2014-04-04T22:29:18Z</timestamp>
+ <contributor>
+ <username>Tester</username>
+ <id>1</id>
+ </contributor>
+ <text xml:space="preserve" bytes="17">[[Category:Main]]</text>
+ </revision>
+ </page>
+</mediawiki>
+
diff --git a/tests/phpunit/data/less/common/test.common.mixins.less b/tests/phpunit/data/less/common/test.common.mixins.less
index 2fbe9b79..40647291 100644
--- a/tests/phpunit/data/less/common/test.common.mixins.less
+++ b/tests/phpunit/data/less/common/test.common.mixins.less
@@ -1,5 +1,4 @@
.test-mixin (@value) {
color: @value;
border: @foo solid @Foo;
- line-height: test-sum(@bar, 10, 20);
}
diff --git a/tests/phpunit/data/less/module/styles.css b/tests/phpunit/data/less/module/styles.css
index b78780a9..bac695b9 100644
--- a/tests/phpunit/data/less/module/styles.css
+++ b/tests/phpunit/data/less/module/styles.css
@@ -1,6 +1,5 @@
/* @noflip */
.unit-tests {
- color: green;
+ color: #008000;
border: 2px solid #eeeeee;
- line-height: 35;
}
diff --git a/tests/phpunit/data/media/2_webp_a.webp b/tests/phpunit/data/media/2_webp_a.webp
new file mode 100644
index 00000000..8764f066
--- /dev/null
+++ b/tests/phpunit/data/media/2_webp_a.webp
Binary files differ
diff --git a/tests/phpunit/data/media/2_webp_ll.webp b/tests/phpunit/data/media/2_webp_ll.webp
new file mode 100644
index 00000000..5794bbf2
--- /dev/null
+++ b/tests/phpunit/data/media/2_webp_ll.webp
Binary files differ
diff --git a/tests/phpunit/data/media/srgb.jpg b/tests/phpunit/data/media/srgb.jpg
new file mode 100644
index 00000000..b965dc4f
--- /dev/null
+++ b/tests/phpunit/data/media/srgb.jpg
Binary files differ
diff --git a/tests/phpunit/data/media/tinyrgb.icc b/tests/phpunit/data/media/tinyrgb.icc
new file mode 100644
index 00000000..eab973f5
--- /dev/null
+++ b/tests/phpunit/data/media/tinyrgb.icc
Binary files differ
diff --git a/tests/phpunit/data/media/tinyrgb.jpg b/tests/phpunit/data/media/tinyrgb.jpg
new file mode 100644
index 00000000..12a8e09f
--- /dev/null
+++ b/tests/phpunit/data/media/tinyrgb.jpg
Binary files differ
diff --git a/tests/phpunit/data/media/webp_animated.webp b/tests/phpunit/data/media/webp_animated.webp
new file mode 100644
index 00000000..25c6a4dd
--- /dev/null
+++ b/tests/phpunit/data/media/webp_animated.webp
Binary files differ
diff --git a/tests/phpunit/data/templates/bad_partial.mustache b/tests/phpunit/data/templates/bad_partial.mustache
new file mode 100644
index 00000000..d2767f0f
--- /dev/null
+++ b/tests/phpunit/data/templates/bad_partial.mustache
@@ -0,0 +1 @@
+Partial {{>nonexistenttemplate}} in here
diff --git a/tests/phpunit/data/templates/has_partial.mustache b/tests/phpunit/data/templates/has_partial.mustache
new file mode 100644
index 00000000..504387a4
--- /dev/null
+++ b/tests/phpunit/data/templates/has_partial.mustache
@@ -0,0 +1 @@
+Partial {{>foobar_args}} in here
diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php
index 19741621..7b0de866 100644
--- a/tests/phpunit/includes/BlockTest.php
+++ b/tests/phpunit/includes/BlockTest.php
@@ -38,9 +38,13 @@ class BlockTest extends MediaWikiLangTestCase {
$oldBlock->delete();
}
- $this->block = new Block( 'UTBlockee', $user->getID(), 0,
- 'Parce que', 0, false, time() + 100500
+ $blockOptions = array(
+ 'address' => 'UTBlockee',
+ 'user' => $user->getID(),
+ 'reason' => 'Parce que',
+ 'expiry' => time() + 100500,
);
+ $this->block = new Block( $blockOptions );
$this->madeAt = wfTimestamp( TS_MW );
$this->block->insert();
@@ -151,22 +155,19 @@ class BlockTest extends MediaWikiLangTestCase {
);
// Foreign perspective (blockee not on current wiki)...
- $block = new Block(
- /* $address */ $username,
- /* $user */ 14146,
- /* $by */ 0,
- /* $reason */ 'crosswiki block...',
- /* $timestamp */ wfTimestampNow(),
- /* $auto */ false,
- /* $expiry */ $this->db->getInfinity(),
- /* anonOnly */ false,
- /* $createAccount */ true,
- /* $enableAutoblock */ true,
- /* $hideName (ipb_deleted) */ true,
- /* $blockEmail */ true,
- /* $allowUsertalk */ false,
- /* $byName */ 'MetaWikiUser'
+ $blockOptions = array(
+ 'address' => $username,
+ 'user' => 14146,
+ 'reason' => 'crosswiki block...',
+ 'timestamp' => wfTimestampNow(),
+ 'expiry' => $this->db->getInfinity(),
+ 'createAccount' => true,
+ 'enableAutoblock' => true,
+ 'hideName' => true,
+ 'blockEmail' => true,
+ 'byText' => 'MetaWikiUser',
);
+ $block = new Block( $blockOptions );
$block->insert();
// Reload block from DB
@@ -208,22 +209,19 @@ class BlockTest extends MediaWikiLangTestCase {
$this->db->update( 'user', array( 'user_id' => 14146 ), array( 'user_id' => $user->getId() ) );
// Foreign perspective (blockee not on current wiki)...
- $block = new Block(
- /* $address */ 'UserOnForeignWiki',
- /* $user */ 14146,
- /* $by */ 0,
- /* $reason */ 'crosswiki block...',
- /* $timestamp */ wfTimestampNow(),
- /* $auto */ false,
- /* $expiry */ $this->db->getInfinity(),
- /* anonOnly */ false,
- /* $createAccount */ true,
- /* $enableAutoblock */ true,
- /* $hideName (ipb_deleted) */ true,
- /* $blockEmail */ true,
- /* $allowUsertalk */ false,
- /* $byName */ 'MetaWikiUser'
+ $blockOptions = array(
+ 'address' => 'UserOnForeignWiki',
+ 'user' => 14146,
+ 'reason' => 'crosswiki block...',
+ 'timestamp' => wfTimestampNow(),
+ 'expiry' => $this->db->getInfinity(),
+ 'createAccount' => true,
+ 'enableAutoblock' => true,
+ 'hideName' => true,
+ 'blockEmail' => true,
+ 'byText' => 'MetaWikiUser',
);
+ $block = new Block( $blockOptions );
$res = $block->insert( $this->db );
$this->assertTrue( (bool)$res['id'], 'Block succeeded' );
@@ -367,4 +365,56 @@ class BlockTest extends MediaWikiLangTestCase {
$block = Block::chooseBlock( $xffblocks, $list );
$this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff );
}
+
+ public function testDeprecatedConstructor() {
+ $this->hideDeprecated( 'Block::__construct with multiple arguments' );
+ $username = 'UnthinkablySecretRandomUsername';
+ $reason = 'being irrational';
+
+ # Set up the target
+ $u = User::newFromName( $username );
+ if ( $u->getID() == 0 ) {
+ $u->setPassword( 'TotallyObvious' );
+ $u->addToDatabase();
+ }
+ unset( $u );
+
+ # Make sure the user isn't blocked
+ $this->assertNull(
+ Block::newFromTarget( $username ),
+ "$username should not be blocked"
+ );
+
+ # Perform the block
+ $block = new Block(
+ /* address */ $username,
+ /* user */ 0,
+ /* by */ 0,
+ /* reason */ $reason,
+ /* timestamp */ 0,
+ /* auto */ false,
+ /* expiry */ 0
+ );
+ $block->insert();
+
+ # Check target
+ $this->assertEquals(
+ $block->getTarget()->getName(),
+ $username,
+ "Target should be set properly"
+ );
+
+ # Check supplied parameter
+ $this->assertEquals(
+ $block->mReason,
+ $reason,
+ "Reason should be non-default"
+ );
+
+ # Check default parameter
+ $this->assertFalse(
+ (bool)$block->prevents( 'createaccount' ),
+ "Account creation should not be blocked by default"
+ );
+ }
}
diff --git a/tests/phpunit/includes/ConsecutiveParametersMatcher.php b/tests/phpunit/includes/ConsecutiveParametersMatcher.php
new file mode 100644
index 00000000..adf74bb4
--- /dev/null
+++ b/tests/phpunit/includes/ConsecutiveParametersMatcher.php
@@ -0,0 +1,123 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which looks for sets of specific parameters in the invocations.
+ *
+ * Checks the parameters of the incoming invocations, the parameter list is
+ * checked against the defined constraints in $parameters. If the constraint
+ * is met it will return true in matches().
+ *
+ * It takes a list of match groups and and increases a call index after each invocation.
+ * So the first invocation uses the first group of constraints, the second the next and so on.
+ */
+class PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
+{
+ /**
+ * @var array
+ */
+ private $_parameterGroups = array();
+
+ /**
+ * @var array
+ */
+ private $_invocations = array();
+
+ /**
+ * @param array $parameterGroups
+ */
+ public function __construct(array $parameterGroups)
+ {
+ foreach ($parameterGroups as $index => $parameters) {
+ foreach ($parameters as $parameter) {
+ if (!($parameter instanceof \PHPUnit_Framework_Constraint)) {
+ $parameter = new \PHPUnit_Framework_Constraint_IsEqual($parameter);
+ }
+ $this->_parameterGroups[$index][] = $parameter;
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ $text = 'with consecutive parameters';
+
+ return $text;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $this->_invocations[] = $invocation;
+ $callIndex = count($this->_invocations) - 1;
+ $this->verifyInvocation($invocation, $callIndex);
+
+ return false;
+ }
+
+ public function verify()
+ {
+ foreach ($this->_invocations as $callIndex => $invocation) {
+ $this->verifyInvocation($invocation, $callIndex);
+ }
+ }
+
+ /**
+ * Verify a single invocation
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ * @param int $callIndex
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ private function verifyInvocation(PHPUnit_Framework_MockObject_Invocation $invocation, $callIndex)
+ {
+
+ if (isset($this->_parameterGroups[$callIndex])) {
+ $parameters = $this->_parameterGroups[$callIndex];
+ } else {
+ // no parameter assertion for this call index
+ return;
+ }
+
+ if ($invocation === null) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ 'Mocked method does not exist.'
+ );
+ }
+
+ if (count($invocation->parameters) < count($parameters)) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf(
+ 'Parameter count for invocation %s is too low.',
+ $invocation->toString()
+ )
+ );
+ }
+
+ foreach ($parameters as $i => $parameter) {
+ $parameter->evaluate(
+ $invocation->parameters[$i],
+ sprintf(
+ 'Parameter %s for invocation #%d %s does not match expected ' .
+ 'value.',
+ $i,
+ $callIndex,
+ $invocation->toString()
+ )
+ );
+ }
+ }
+}
diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php
index 15778e40..27959b1d 100644
--- a/tests/phpunit/includes/EditPageTest.php
+++ b/tests/phpunit/includes/EditPageTest.php
@@ -11,6 +11,28 @@
*/
class EditPageTest extends MediaWikiLangTestCase {
+ protected function setUp() {
+ global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
+
+ parent::setUp();
+
+ $this->setMwGlobals( array(
+ 'wgExtraNamespaces' => $wgExtraNamespaces,
+ 'wgNamespaceContentModels' => $wgNamespaceContentModels,
+ 'wgContentHandlers' => $wgContentHandlers,
+ 'wgContLang' => $wgContLang,
+ ) );
+
+ $wgExtraNamespaces[12312] = 'Dummy';
+ $wgExtraNamespaces[12313] = 'Dummy_talk';
+
+ $wgNamespaceContentModels[12312] = "testing";
+ $wgContentHandlers["testing"] = 'DummyContentHandlerForTesting';
+
+ MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
+ $wgContLang->resetNamespaces(); # reset namespace cache
+ }
+
/**
* @dataProvider provideExtractSectionTitle
* @covers EditPage::extractSectionTitle
@@ -499,4 +521,37 @@ hello
$this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Berta', $bertasEdit,
$expectedCode, $expectedText, $message );
}
+
+ /**
+ * @depends testAutoMerge
+ */
+ public function testCheckDirectEditingDisallowed_forNonTextContent() {
+ $title = Title::newFromText( 'Dummy:NonTextPageForEditPage' );
+ $page = WikiPage::factory( $title );
+
+ $article = new Article( $title );
+ $article->getContext()->setTitle( $title );
+ $ep = new EditPage( $article );
+ $ep->setContextTitle( $title );
+
+ $user = $GLOBALS['wgUser'];
+
+ $edit = array(
+ 'wpTextbox1' => serialize( 'non-text content' ),
+ 'wpEditToken' => $user->getEditToken(),
+ 'wpEdittime' => '',
+ 'wpStarttime' => wfTimestampNow()
+ );
+
+ $req = new FauxRequest( $edit, true );
+ $ep->importFormData( $req );
+
+ $this->setExpectedException(
+ 'MWException',
+ 'This content model is not supported: testing'
+ );
+
+ $ep->internalAttemptSave( $result, false );
+ }
+
}
diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php
index 4a4130e0..7b60fb3f 100644
--- a/tests/phpunit/includes/ExtraParserTest.php
+++ b/tests/phpunit/includes/ExtraParserTest.php
@@ -2,6 +2,8 @@
/**
* Parser-related tests that don't suit for parserTests.txt
+ *
+ * @group Database
*/
class ExtraParserTest extends MediaWikiTestCase {
@@ -20,7 +22,6 @@ class ExtraParserTest extends MediaWikiTestCase {
'wgContLang' => $contLang,
'wgLang' => Language::factory( 'en' ),
'wgMemc' => new EmptyBagOStuff,
- 'wgAlwaysUseTidy' => false,
'wgCleanSignatures' => true,
) );
diff --git a/tests/phpunit/includes/FauxRequestTest.php b/tests/phpunit/includes/FauxRequestTest.php
index 745a5b42..07214b21 100644
--- a/tests/phpunit/includes/FauxRequestTest.php
+++ b/tests/phpunit/includes/FauxRequestTest.php
@@ -6,13 +6,46 @@ class FauxRequestTest extends MediaWikiTestCase {
* @covers FauxRequest::getHeader
*/
public function testGetSetHeader() {
- $value = 'test/test';
+ $value = 'text/plain, text/html';
$request = new FauxRequest();
- $request->setHeader( 'Content-Type', $value );
+ $request->setHeader( 'Accept', $value );
- $this->assertEquals( $request->getHeader( 'Content-Type' ), $value );
- $this->assertEquals( $request->getHeader( 'CONTENT-TYPE' ), $value );
- $this->assertEquals( $request->getHeader( 'content-type' ), $value );
+ $this->assertEquals( $request->getHeader( 'Nonexistent' ), false );
+ $this->assertEquals( $request->getHeader( 'Accept' ), $value );
+ $this->assertEquals( $request->getHeader( 'ACCEPT' ), $value );
+ $this->assertEquals( $request->getHeader( 'accept' ), $value );
+ $this->assertEquals(
+ $request->getHeader( 'Accept', WebRequest::GETHEADER_LIST ),
+ array( 'text/plain', 'text/html' )
+ );
+ }
+
+ /**
+ * @covers FauxRequest::getAllHeaders
+ */
+ public function testGetAllHeaders() {
+ $_SERVER['HTTP_TEST'] = 'Example';
+
+ $request = new FauxRequest();
+
+ $this->assertEquals(
+ array(),
+ $request->getAllHeaders()
+ );
+ }
+
+ /**
+ * @covers FauxRequest::getHeader
+ */
+ public function testGetHeader() {
+ $_SERVER['HTTP_TEST'] = 'Example';
+
+ $request = new FauxRequest();
+
+ $this->assertEquals(
+ false,
+ $request->getHeader( 'test' )
+ );
}
}
diff --git a/tests/phpunit/includes/FauxResponseTest.php b/tests/phpunit/includes/FauxResponseTest.php
index 4a974ba2..39a0effa 100644
--- a/tests/phpunit/includes/FauxResponseTest.php
+++ b/tests/phpunit/includes/FauxResponseTest.php
@@ -108,6 +108,13 @@ class FauxResponseTest extends MediaWikiTestCase {
'Third parameter overrides the HTTP/... header'
);
+ $this->response->statusHeader( 210 );
+ $this->assertEquals(
+ 210,
+ $this->response->getStatusCode(),
+ 'Handle statusHeader method'
+ );
+
$this->response->header( 'Location: http://localhost/', false, 206 );
$this->assertEquals(
206,
diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php
index 1e30273e..e89e36f6 100644
--- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php
+++ b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php
@@ -666,9 +666,9 @@ class GlobalTest extends MediaWikiTestCase {
public function testWfMkdirParents() {
// Should not return true if file exists instead of directory
$fname = $this->getNewTempFile();
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$ok = wfMkdirParents( $fname );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
$this->assertFalse( $ok );
}
@@ -687,6 +687,105 @@ class GlobalTest extends MediaWikiTestCase {
$this->assertEquals( $expected, $actual, $description );
}
+ public function wfWikiID() {
+ $this->setMwGlobals( array(
+ 'wgDBname' => 'example',
+ 'wgDBprefix' => '',
+ ) );
+ $this->assertEquals(
+ wfWikiID(),
+ 'example'
+ );
+
+ $this->setMwGlobals( array(
+ 'wgDBname' => 'example',
+ 'wgDBprefix' => 'mw_',
+ ) );
+ $this->assertEquals(
+ wfWikiID(),
+ 'example-mw_'
+ );
+ }
+
+ public function testWfMemcKey() {
+ // Just assert the exact output so we can catch unintentional changes to key
+ // construction, which would effectively invalidate all existing cache.
+
+ $this->setMwGlobals( array(
+ 'wgCachePrefix' => false,
+ 'wgDBname' => 'example',
+ 'wgDBprefix' => '',
+ ) );
+ $this->assertEquals(
+ wfMemcKey( 'foo', '123', 'bar' ),
+ 'example:foo:123:bar'
+ );
+
+ $this->setMwGlobals( array(
+ 'wgCachePrefix' => false,
+ 'wgDBname' => 'example',
+ 'wgDBprefix' => 'mw_',
+ ) );
+ $this->assertEquals(
+ wfMemcKey( 'foo', '123', 'bar' ),
+ 'example-mw_:foo:123:bar'
+ );
+
+ $this->setMwGlobals( array(
+ 'wgCachePrefix' => 'custom',
+ 'wgDBname' => 'example',
+ 'wgDBprefix' => 'mw_',
+ ) );
+ $this->assertEquals(
+ wfMemcKey( 'foo', '123', 'bar' ),
+ 'custom:foo:123:bar'
+ );
+ }
+
+ public function testWfForeignMemcKey() {
+ $this->setMwGlobals( array(
+ 'wgCachePrefix' => false,
+ 'wgDBname' => 'example',
+ 'wgDBprefix' => '',
+ ) );
+ $local = wfMemcKey( 'foo', 'bar' );
+
+ $this->setMwGlobals( array(
+ 'wgDBname' => 'other',
+ 'wgDBprefix' => 'mw_',
+ ) );
+ $this->assertEquals(
+ wfForeignMemcKey( 'example', '', 'foo', 'bar' ),
+ $local,
+ 'Match output of wfMemcKey from local wiki'
+ );
+ }
+
+ public function testWfGlobalCacheKey() {
+ $this->setMwGlobals( array(
+ 'wgCachePrefix' => 'ignored',
+ 'wgDBname' => 'example',
+ 'wgDBprefix' => ''
+ ) );
+ $one = wfGlobalCacheKey( 'some', 'thing' );
+ $this->assertEquals(
+ $one,
+ 'global:some:thing'
+ );
+
+ $this->setMwGlobals( array(
+ 'wgDBname' => 'other',
+ 'wgDBprefix' => 'mw_'
+ ) );
+ $two = wfGlobalCacheKey( 'some', 'thing' );
+
+ $this->assertEquals(
+ $one,
+ $two,
+ 'Not fragmented by wiki id'
+ );
+ }
+
public static function provideWfShellWikiCmdList() {
global $wgPhpCli;
diff --git a/tests/phpunit/includes/GlobalFunctions/wfArrayPlus2dTest.php b/tests/phpunit/includes/GlobalFunctions/wfArrayPlus2dTest.php
new file mode 100644
index 00000000..88875bb0
--- /dev/null
+++ b/tests/phpunit/includes/GlobalFunctions/wfArrayPlus2dTest.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * @group GlobalFunctions
+ * @covers ::wfArrayPlus2d
+ */
+class WfArrayPlus2dTest extends MediaWikiTestCase {
+ /**
+ * @dataProvider provideArrays
+ */
+ public function testWfArrayPlus2d( $baseArray, $newValues, $expected, $testName ) {
+ $this->assertEquals(
+ $expected,
+ wfArrayPlus2d( $baseArray, $newValues ),
+ $testName
+ );
+ }
+
+ /**
+ * Provider for testing wfArrayPlus2d
+ *
+ * @return array
+ */
+ public static function provideArrays() {
+ return array(
+ // target array, new values array, expected result
+ array(
+ array( 0 => '1dArray' ),
+ array( 1 => '1dArray' ),
+ array( 0 => '1dArray', 1 => '1dArray' ),
+ "Test simple union of two arrays with different keys",
+ ),
+ array(
+ array(
+ 0 => array( 0 => '2dArray' ),
+ ),
+ array(
+ 0 => array( 1 => '2dArray' ),
+ ),
+ array(
+ 0 => array( 0 => '2dArray', 1 => '2dArray' ),
+ ),
+ "Test union of 2d arrays with different keys in the value array",
+ ),
+ array(
+ array(
+ 0 => array( 0 => '2dArray' ),
+ ),
+ array(
+ 0 => array( 0 => '1dArray' ),
+ ),
+ array(
+ 0 => array( 0 => '2dArray' ),
+ ),
+ "Test union of 2d arrays with same keys in the value array",
+ ),
+ array(
+ array(
+ 0 => array( 0 => array( 0 => '3dArray' ) ),
+ ),
+ array(
+ 0 => array( 0 => array( 1 => '2dArray' ) ),
+ ),
+ array(
+ 0 => array( 0 => array( 0 => '3dArray' ) ),
+ ),
+ "Test union of 3d array with different keys",
+ ),
+ array(
+ array(
+ 0 => array( 0 => array( 0 => '3dArray' ) ),
+ ),
+ array(
+ 0 => array( 1 => array( 0 => '2dArray' ) ),
+ ),
+ array(
+ 0 => array( 0 => array( 0 => '3dArray' ), 1 => array( 0 => '2dArray' ) ),
+ ),
+ "Test union of 3d array with different keys in the value array",
+ ),
+ array(
+ array(
+ 0 => array( 0 => array( 0 => '3dArray' ) ),
+ ),
+ array(
+ 0 => array( 0 => array( 0 => '2dArray' ) ),
+ ),
+ array(
+ 0 => array( 0 => array( 0 => '3dArray' ) ),
+ ),
+ "Test union of 3d array with same keys in the value array",
+ ),
+ );
+ }
+}
diff --git a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php
index bea496c4..4ce51c6a 100644
--- a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php
+++ b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php
@@ -21,6 +21,7 @@ class WfTimestampTest extends MediaWikiTestCase {
array( -30281104, TS_MW, '19690115123456', 'Negative TS_UNIX to TS_MW' ),
array( $t, TS_UNIX, 979562096, 'TS_UNIX to TS_UNIX' ),
array( $t, TS_DB, '2001-01-15 12:34:56', 'TS_UNIX to TS_DB' ),
+ array( $t + .01, TS_MW, '20010115123456', 'TS_UNIX float to TS_MW' ),
array( $t, TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_ISO_8601_BASIC to TS_DB' ),
diff --git a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
index d11668b7..d4df7b00 100644
--- a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
+++ b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
@@ -112,6 +112,8 @@ class WfUrlencodeTest extends MediaWikiTestCase {
### Other tests
// slash remain unchanged. %2F seems to break things
array( '/', '/' ),
+ // T105265
+ array( '~', '~' ),
// Other 'funnies' chars
array( '[]', '%5B%5D' ),
diff --git a/tests/phpunit/includes/ImportLinkCacheIntegrationTest.php b/tests/phpunit/includes/ImportLinkCacheIntegrationTest.php
new file mode 100644
index 00000000..1433b898
--- /dev/null
+++ b/tests/phpunit/includes/ImportLinkCacheIntegrationTest.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Integration test that checks import success and
+ * LinkCache integration.
+ *
+ * @group medium
+ * @group Database
+ *
+ * @author mwjames
+ */
+class ImportLinkCacheIntegrationTest extends MediaWikiTestCase {
+
+ private $importStreamSource;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $file = dirname( __DIR__ ) . '/data/import/ImportLinkCacheIntegrationTest.xml';
+
+ $this->importStreamSource = ImportStreamSource::newFromFile( $file );
+
+ if ( !$this->importStreamSource->isGood() ) {
+ throw new Exception( "Import source for {$file} failed" );
+ }
+ }
+
+ public function testImportForImportSource() {
+
+ $this->doImport( $this->importStreamSource );
+
+ // Imported title
+ $loremIpsum = Title::newFromText( 'Lorem ipsum' );
+
+ $this->assertSame(
+ $loremIpsum->getArticleID(),
+ $loremIpsum->getArticleID( Title::GAID_FOR_UPDATE )
+ );
+
+ $categoryLoremIpsum = Title::newFromText( 'Category:Lorem ipsum' );
+
+ $this->assertSame(
+ $categoryLoremIpsum->getArticleID(),
+ $categoryLoremIpsum->getArticleID( Title::GAID_FOR_UPDATE )
+ );
+
+ $page = new WikiPage( $loremIpsum );
+ $page->doDeleteArticle( 'import test: delete page' );
+
+ $page = new WikiPage( $categoryLoremIpsum );
+ $page->doDeleteArticle( 'import test: delete page' );
+ }
+
+ /**
+ * @depends testImportForImportSource
+ */
+ public function testReImportForImportSource() {
+
+ $this->doImport( $this->importStreamSource );
+
+ // ReImported title
+ $loremIpsum = Title::newFromText( 'Lorem ipsum' );
+
+ $this->assertSame(
+ $loremIpsum->getArticleID(),
+ $loremIpsum->getArticleID( Title::GAID_FOR_UPDATE )
+ );
+
+ $categoryLoremIpsum = Title::newFromText( 'Category:Lorem ipsum' );
+
+ $this->assertSame(
+ $categoryLoremIpsum->getArticleID(),
+ $categoryLoremIpsum->getArticleID( Title::GAID_FOR_UPDATE )
+ );
+ }
+
+ private function doImport( $importStreamSource ) {
+
+ $importer = new WikiImporter(
+ $importStreamSource->value,
+ ConfigFactory::getDefaultInstance()->makeConfig( 'main' )
+ );
+ $importer->setDebug( true );
+
+ $reporter = new ImportReporter(
+ $importer,
+ false,
+ '',
+ false
+ );
+
+ $reporter->setContext( new RequestContext() );
+ $reporter->open();
+ $exception = false;
+
+ try {
+ $importer->doImport();
+ } catch ( Exception $e ) {
+ $exception = $e;
+ }
+
+ $result = $reporter->close();
+
+ $this->assertFalse(
+ $exception
+ );
+
+ $this->assertTrue(
+ $result->isGood()
+ );
+ }
+
+}
diff --git a/tests/phpunit/includes/LinkFilterTest.php b/tests/phpunit/includes/LinkFilterTest.php
index f2c9cb43..68081059 100644
--- a/tests/phpunit/includes/LinkFilterTest.php
+++ b/tests/phpunit/includes/LinkFilterTest.php
@@ -76,7 +76,7 @@ class LinkFilterTest extends MediaWikiLangTestCase {
array( 'https://', '*.com', 'https://name:pass@secure.com/index.html' ),
array( 'http://', 'name:pass@test.com', 'http://test.com' ),
array( 'http://', 'test.com', 'http://name:pass@test.com' ),
- array( 'http://', '*.test.com', 'http://a.b.c.test.com/dir/dir/file?a=6'),
+ array( 'http://', '*.test.com', 'http://a.b.c.test.com/dir/dir/file?a=6' ),
array( null, 'http://*.test.com', 'http://www.test.com' ),
array( 'mailto:', 'name@mail.test123.com', 'mailto:name@mail.test123.com' ),
array( '',
@@ -122,8 +122,8 @@ class LinkFilterTest extends MediaWikiLangTestCase {
array( '', 'git://github.com/prwef/abc-def.git', 'git://github.com/prwef/abc-def.git' ),
array( 'git://', 'github.com/', 'git://github.com/prwef/abc-def.git' ),
array( 'git://', '*.github.com/', 'git://a.b.c.d.e.f.github.com/prwef/abc-def.git' ),
- array( '', 'gopher://*.test.com/', 'gopher://gopher.test.com/0/v2/vstat'),
- array( 'telnet://', '*.test.com', 'telnet://shell.test.com/~home/'),
+ array( '', 'gopher://*.test.com/', 'gopher://gopher.test.com/0/v2/vstat' ),
+ array( 'telnet://', '*.test.com', 'telnet://shell.test.com/~home/' ),
//
// The following only work in PHP >= 5.3.7, due to a bug in parse_url which eats
@@ -243,10 +243,10 @@ class LinkFilterTest extends MediaWikiLangTestCase {
array( 'http://*.test.*' ),
array( 'http://*test.com' ),
array( 'https://*' ),
- array( '*://test.com'),
+ array( '*://test.com' ),
array( 'mailto:name:pass@t*est.com' ),
- array( 'http://*:888/'),
- array( '*http://'),
+ array( 'http://*:888/' ),
+ array( '*http://' ),
array( 'test.com/*/index' ),
array( 'test.com/dir/index?arg=*' ),
);
diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php
index 823c9330..a3efbb8d 100644
--- a/tests/phpunit/includes/LinkerTest.php
+++ b/tests/phpunit/includes/LinkerTest.php
@@ -93,12 +93,26 @@ class LinkerTest extends MediaWikiLangTestCase {
* @covers Linker::formatAutocomments
* @covers Linker::formatLinksInComment
*/
- public function testFormatComment( $expected, $comment, $title = false, $local = false ) {
+ public function testFormatComment( $expected, $comment, $title = false, $local = false, $wikiId = null ) {
+ $conf = new SiteConfiguration();
+ $conf->settings = array(
+ 'wgServer' => array(
+ 'enwiki' => '//en.example.org',
+ 'dewiki' => '//de.example.org',
+ ),
+ 'wgArticlePath' => array(
+ 'enwiki' => '/w/$1',
+ 'dewiki' => '/w/$1',
+ ),
+ );
+ $conf->suffixes = array( 'wiki' );
+
$this->setMwGlobals( array(
'wgScript' => '/wiki/index.php',
'wgArticlePath' => '/wiki/$1',
'wgWellFormedXml' => true,
'wgCapitalLinks' => true,
+ 'wgConf' => $conf,
) );
if ( $title === false ) {
@@ -108,11 +122,13 @@ class LinkerTest extends MediaWikiLangTestCase {
$this->assertEquals(
$expected,
- Linker::formatComment( $comment, $title, $local )
+ Linker::formatComment( $comment, $title, $local, $wikiId )
);
}
- public static function provideCasesForFormatComment() {
+ public function provideCasesForFormatComment() {
+ $wikiId = 'enwiki'; // $wgConf has a fake entry for this
+
return array(
// Linker::formatComment
array(
@@ -127,6 +143,10 @@ class LinkerTest extends MediaWikiLangTestCase {
"&#039;&#039;&#039;not bolded&#039;&#039;&#039;",
"'''not bolded'''",
),
+ array(
+ "try &lt;script&gt;evil&lt;/scipt&gt; things",
+ "try <script>evil</scipt> things",
+ ),
// Linker::formatAutocomments
array(
'<a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→</a>‎<span dir="auto"><span class="autocomment">autocomment</span></span>',
@@ -157,6 +177,14 @@ class LinkerTest extends MediaWikiLangTestCase {
"/* autocomment containing /* */ T70361"
),
array(
+ '<a href="/wiki/Special:BlankPage#autocomment_containing_.22quotes.22" title="Special:BlankPage">→</a>‎<span dir="auto"><span class="autocomment">autocomment containing &quot;quotes&quot;</span></span>',
+ "/* autocomment containing \"quotes\" */"
+ ),
+ array(
+ '<a href="/wiki/Special:BlankPage#autocomment_containing_.3Cscript.3Etags.3C.2Fscript.3E" title="Special:BlankPage">→</a>‎<span dir="auto"><span class="autocomment">autocomment containing &lt;script&gt;tags&lt;/script&gt;</span></span>',
+ "/* autocomment containing <script>tags</script> */"
+ ),
+ array(
'<a href="#autocomment">→</a>‎<span dir="auto"><span class="autocomment">autocomment</span></span>',
"/* autocomment */",
false, true
@@ -166,6 +194,16 @@ class LinkerTest extends MediaWikiLangTestCase {
"/* autocomment */",
null
),
+ array(
+ '<a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→</a>‎<span dir="auto"><span class="autocomment">autocomment</span></span>',
+ "/* autocomment */",
+ false, false
+ ),
+ array(
+ '<a class="external" rel="nofollow" href="//en.example.org/w/Special:BlankPage#autocomment">→</a>‎<span dir="auto"><span class="autocomment">autocomment</span></span>',
+ "/* autocomment */",
+ false, false, $wikiId
+ ),
// Linker::formatLinksInComment
array(
'abc <a href="/wiki/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> def',
@@ -191,6 +229,28 @@ class LinkerTest extends MediaWikiLangTestCase {
'abc <a href="/wiki/index.php?title=/subpage&amp;action=edit&amp;redlink=1" class="new" title="/subpage (page does not exist)">/subpage</a> def',
"abc [[/subpage]] def",
),
+ array(
+ 'abc <a href="/wiki/index.php?title=%22evil!%22&amp;action=edit&amp;redlink=1" class="new" title="&quot;evil!&quot; (page does not exist)">&quot;evil!&quot;</a> def',
+ "abc [[\"evil!\"]] def",
+ ),
+ array(
+ 'abc [[&lt;script&gt;very evil&lt;/script&gt;]] def',
+ "abc [[<script>very evil</script>]] def",
+ ),
+ array(
+ 'abc [[|]] def',
+ "abc [[|]] def",
+ ),
+ array(
+ 'abc <a href="/wiki/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> def',
+ "abc [[link]] def",
+ false, false
+ ),
+ array(
+ 'abc <a class="external" rel="nofollow" href="//en.example.org/w/Link">link</a> def',
+ "abc [[link]] def",
+ false, false, $wikiId
+ )
);
}
diff --git a/tests/phpunit/includes/MediaWikiTest.php b/tests/phpunit/includes/MediaWikiTest.php
new file mode 100644
index 00000000..e1962436
--- /dev/null
+++ b/tests/phpunit/includes/MediaWikiTest.php
@@ -0,0 +1,157 @@
+<?php
+
+class MediaWikiTest extends MediaWikiTestCase {
+ protected function setUp() {
+ parent::setUp();
+
+ $this->setMwGlobals( array(
+ 'wgServer' => 'http://example.org',
+ 'wgScriptPath' => '/w',
+ 'wgScript' => '/w/index.php',
+ 'wgArticlePath' => '/wiki/$1',
+ 'wgActionPaths' => array(),
+ ) );
+ }
+
+ public static function provideTryNormaliseRedirect() {
+ return array(
+ array(
+ // View: Canonical
+ 'url' => 'http://example.org/wiki/Foo_Bar',
+ 'query' => array(),
+ 'title' => 'Foo_Bar',
+ 'redirect' => false,
+ ),
+ array(
+ // View: Escaped title
+ 'url' => 'http://example.org/wiki/Foo%20Bar',
+ 'query' => array(),
+ 'title' => 'Foo_Bar',
+ 'redirect' => 'http://example.org/wiki/Foo_Bar',
+ ),
+ array(
+ // View: Script path
+ 'url' => 'http://example.org/w/index.php?title=Foo_Bar',
+ 'query' => array( 'title' => 'Foo_Bar' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => 'http://example.org/wiki/Foo_Bar',
+ ),
+ array(
+ // View: Script path with implicit title from page id
+ 'url' => 'http://example.org/w/index.php?curid=123',
+ 'query' => array( 'curid' => '123' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => false,
+ ),
+ array(
+ // View: Script path with implicit title from revision id
+ 'url' => 'http://example.org/w/index.php?oldid=123',
+ 'query' => array( 'oldid' => '123' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => false,
+ ),
+ array(
+ // View: Script path without title
+ 'url' => 'http://example.org/w/index.php',
+ 'query' => array(),
+ 'title' => 'Main_Page',
+ 'redirect' => 'http://example.org/wiki/Main_Page',
+ ),
+ array(
+ // View: Script path with empty title
+ 'url' => 'http://example.org/w/index.php?title=',
+ 'query' => array( 'title' => '' ),
+ 'title' => 'Main_Page',
+ 'redirect' => 'http://example.org/wiki/Main_Page',
+ ),
+ array(
+ // View: Index with escaped title
+ 'url' => 'http://example.org/w/index.php?title=Foo%20Bar',
+ 'query' => array( 'title' => 'Foo Bar' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => 'http://example.org/wiki/Foo_Bar',
+ ),
+ array(
+ // View: Script path with escaped title
+ 'url' => 'http://example.org/w/?title=Foo_Bar',
+ 'query' => array( 'title' => 'Foo_Bar' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => 'http://example.org/wiki/Foo_Bar',
+ ),
+ array(
+ // View: Root path with escaped title
+ 'url' => 'http://example.org/?title=Foo_Bar',
+ 'query' => array( 'title' => 'Foo_Bar' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => 'http://example.org/wiki/Foo_Bar',
+ ),
+ array(
+ // View: Canonical with redundant query
+ 'url' => 'http://example.org/wiki/Foo_Bar?action=view',
+ 'query' => array( 'action' => 'view' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => 'http://example.org/wiki/Foo_Bar',
+ ),
+ array(
+ // Edit: Canonical view url with action query
+ 'url' => 'http://example.org/wiki/Foo_Bar?action=edit',
+ 'query' => array( 'action' => 'edit' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => false,
+ ),
+ array(
+ // View: Index with action query
+ 'url' => 'http://example.org/w/index.php?title=Foo_Bar&action=view',
+ 'query' => array( 'title' => 'Foo_Bar', 'action' => 'view' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => 'http://example.org/wiki/Foo_Bar',
+ ),
+ array(
+ // Edit: Index with action query
+ 'url' => 'http://example.org/w/index.php?title=Foo_Bar&action=edit',
+ 'query' => array( 'title' => 'Foo_Bar', 'action' => 'edit' ),
+ 'title' => 'Foo_Bar',
+ 'redirect' => false,
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideTryNormaliseRedirect
+ * @covers MediaWiki::tryNormaliseRedirect
+ */
+ public function testTryNormaliseRedirect( $url, $query, $title, $expectedRedirect = false ) {
+ // Set SERVER because interpolateTitle() doesn't use getRequestURL(),
+ // whereas tryNormaliseRedirect does().
+ $_SERVER['REQUEST_URI'] = $url;
+
+ $req = new FauxRequest( $query );
+ $req->setRequestURL( $url );
+ // This adds a virtual 'title' query parameter. Normally called from Setup.php
+ $req->interpolateTitle();
+
+ $titleObj = Title::newFromText( $title );
+
+ // Set global context since some involved code paths don't yet have context
+ $context = RequestContext::getMain();
+ $context->setRequest( $req );
+ $context->setTitle( $titleObj );
+
+ $mw = new MediaWiki( $context );
+
+ $method = new ReflectionMethod( $mw, 'tryNormaliseRedirect' );
+ $method->setAccessible( true );
+ $ret = $method->invoke( $mw, $titleObj );
+
+ $this->assertEquals(
+ $expectedRedirect !== false,
+ $ret,
+ 'Return true only when redirecting'
+ );
+
+ $this->assertEquals(
+ $expectedRedirect ?: '',
+ $context->getOutput()->getRedirect()
+ );
+ }
+}
diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php
index 99ec2e42..9c953a6d 100644
--- a/tests/phpunit/includes/MessageTest.php
+++ b/tests/phpunit/includes/MessageTest.php
@@ -21,6 +21,17 @@ class MessageTest extends MediaWikiLangTestCase {
$this->assertEquals( $key, $message->getKey() );
$this->assertEquals( $params, $message->getParams() );
$this->assertEquals( $expectedLang, $message->getLanguage() );
+
+ $messageSpecifier = $this->getMockForAbstractClass( 'MessageSpecifier' );
+ $messageSpecifier->expects( $this->any() )
+ ->method( 'getKey' )->will( $this->returnValue( $key ) );
+ $messageSpecifier->expects( $this->any() )
+ ->method( 'getParams' )->will( $this->returnValue( $params ) );
+ $message = new Message( $messageSpecifier, array(), $language );
+
+ $this->assertEquals( $key, $message->getKey() );
+ $this->assertEquals( $params, $message->getParams() );
+ $this->assertEquals( $expectedLang, $message->getLanguage() );
}
public static function provideConstructor() {
@@ -548,4 +559,26 @@ class MessageTest extends MediaWikiLangTestCase {
public function testInLanguageThrows() {
wfMessage( 'foo' )->inLanguage( 123 );
}
+
+ /**
+ * @covers Message::serialize
+ * @covers Message::unserialize
+ */
+ public function testSerialization() {
+ $msg = new Message( 'parentheses' );
+ $msg->rawParams( '<a>foo</a>' );
+ $msg->title( Title::newFromText( 'Testing' ) );
+ $this->assertEquals( '(<a>foo</a>)', $msg->parse(), 'Sanity check' );
+ $msg = unserialize( serialize( $msg ) );
+ $this->assertEquals( '(<a>foo</a>)', $msg->parse() );
+ $title = TestingAccessWrapper::newFromObject( $msg )->title;
+ $this->assertInstanceOf( 'Title', $title );
+ $this->assertEquals( 'Testing', $title->getFullText() );
+
+ $msg = new Message( 'mainpage' );
+ $msg->inLanguage( 'de' );
+ $this->assertEquals( 'Hauptseite', $msg->plain(), 'Sanity check' );
+ $msg = unserialize( serialize( $msg ) );
+ $this->assertEquals( 'Hauptseite', $msg->plain() );
+ }
}
diff --git a/tests/phpunit/includes/MimeMagicTest.php b/tests/phpunit/includes/MimeMagicTest.php
index 742d3827..3c45f305 100644
--- a/tests/phpunit/includes/MimeMagicTest.php
+++ b/tests/phpunit/includes/MimeMagicTest.php
@@ -1,5 +1,5 @@
<?php
-class MimeMagicTest extends MediaWikiTestCase {
+class MimeMagicTest extends PHPUnit_Framework_TestCase {
/** @var MimeMagic */
private $mimeMagic;
diff --git a/tests/phpunit/includes/MovePageTest.php b/tests/phpunit/includes/MovePageTest.php
index 9501e452..0ef2fa63 100644
--- a/tests/phpunit/includes/MovePageTest.php
+++ b/tests/phpunit/includes/MovePageTest.php
@@ -57,7 +57,7 @@ class MovePageTest extends MediaWikiTestCase {
WikiPage::factory( $oldTitle )->getRevision()
);
$this->assertNotNull(
- WikiPage::factory( $newTitle)->getRevision()
+ WikiPage::factory( $newTitle )->getRevision()
);
}
}
diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php
index 6c6d95ee..f0d905e5 100644
--- a/tests/phpunit/includes/OutputPageTest.php
+++ b/tests/phpunit/includes/OutputPageTest.php
@@ -141,53 +141,36 @@ class OutputPageTest extends MediaWikiTestCase {
// Load module script only
array(
array( 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS ),
- '<script>if(window.mw){
-document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\u0026amp;lang=en\u0026amp;modules=test.foo\u0026amp;only=scripts\u0026amp;skin=fallback\u0026amp;*\"\u003E\u003C/script\u003E");
-}</script>
-'
+ "<script>window.RLQ = window.RLQ || []; window.RLQ.push( function () {\n"
+ . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback");'
+ . "\n} );</script>"
),
array(
// Don't condition wrap raw modules (like the startup module)
array( 'test.raw', ResourceLoaderModule::TYPE_SCRIPTS ),
- '<script src="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.raw&amp;only=scripts&amp;skin=fallback&amp;*"></script>
-'
+ '<script async src="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.raw&amp;only=scripts&amp;skin=fallback"></script>'
),
// Load module styles only
// This also tests the order the modules are put into the url
array(
array( array( 'test.baz', 'test.foo', 'test.bar' ), ResourceLoaderModule::TYPE_STYLES ),
- '<link rel=stylesheet href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.bar%2Cbaz%2Cfoo&amp;only=styles&amp;skin=fallback&amp;*">
-'
+
+ '<link rel=stylesheet href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.bar%2Cbaz%2Cfoo&amp;only=styles&amp;skin=fallback">'
),
// Load private module (only=scripts)
array(
array( 'test.quux', ResourceLoaderModule::TYPE_SCRIPTS ),
- '<script>if(window.mw){
-mw.test.baz({token:123});mw.loader.state({"test.quux":"ready"});
-
-}</script>
-'
+ "<script>window.RLQ = window.RLQ || []; window.RLQ.push( function () {\n"
+ . "mw.test.baz({token:123});mw.loader.state({\"test.quux\":\"ready\"});\n"
+ . "} );</script>"
),
// Load private module (combined)
array(
array( 'test.quux', ResourceLoaderModule::TYPE_COMBINED ),
- '<script>if(window.mw){
-mw.loader.implement("test.quux",function($,jQuery){mw.test.baz({token:123});},{"css":[".mw-icon{transition:none}\n"]});
-
-}</script>
-'
- ),
- // Load module script with ESI
- array(
- array( 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS, true ),
- '<script><esi:include src="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.foo&amp;only=scripts&amp;skin=fallback&amp;*" /></script>
-'
- ),
- // Load module styles with ESI
- array(
- array( 'test.foo', ResourceLoaderModule::TYPE_STYLES, true ),
- '<style><esi:include src="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.foo&amp;only=styles&amp;skin=fallback&amp;*" /></style>
-',
+ "<script>window.RLQ = window.RLQ || []; window.RLQ.push( function () {\n"
+ . "mw.loader.implement(\"test.quux\",function($,jQuery){"
+ . "mw.test.baz({token:123});},{\"css\":[\".mw-icon{transition:none}"
+ . "\"]});\n} );</script>"
),
// Load no modules
array(
@@ -197,19 +180,17 @@ mw.loader.implement("test.quux",function($,jQuery){mw.test.baz({token:123});},{"
// noscript group
array(
array( 'test.noscript', ResourceLoaderModule::TYPE_STYLES ),
- '<noscript><link rel=stylesheet href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.noscript&amp;only=styles&amp;skin=fallback&amp;*"></noscript>
-'
+ '<noscript><link rel=stylesheet href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.noscript&amp;only=styles&amp;skin=fallback"></noscript>'
),
// Load two modules in separate groups
array(
array( array( 'test.group.foo', 'test.group.bar' ), ResourceLoaderModule::TYPE_COMBINED ),
- '<script>if(window.mw){
-document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\u0026amp;lang=en\u0026amp;modules=test.group.bar\u0026amp;skin=fallback\u0026amp;*\"\u003E\u003C/script\u003E");
-}</script>
-<script>if(window.mw){
-document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\u0026amp;lang=en\u0026amp;modules=test.group.foo\u0026amp;skin=fallback\u0026amp;*\"\u003E\u003C/script\u003E");
-}</script>
-'
+ "<script>window.RLQ = window.RLQ || []; window.RLQ.push( function () {\n"
+ . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
+ . "\n} );</script>\n"
+ . "<script>window.RLQ = window.RLQ || []; window.RLQ.push( function () {\n"
+ . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
+ . "\n} );</script>"
),
);
}
@@ -226,7 +207,6 @@ document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\
public function testMakeResourceLoaderLink( $args, $expectedHtml ) {
$this->setMwGlobals( array(
'wgResourceLoaderDebug' => false,
- 'wgResourceLoaderUseESI' => true,
'wgLoadScript' => 'http://127.0.0.1:8080/w/load.php',
// Affects whether CDATA is inserted
'wgWellFormedXml' => false,
@@ -244,63 +224,141 @@ document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\
'test.foo' => new ResourceLoaderTestModule( array(
'script' => 'mw.test.foo( { a: true } );',
'styles' => '.mw-test-foo { content: "style"; }',
- )),
+ ) ),
'test.bar' => new ResourceLoaderTestModule( array(
'script' => 'mw.test.bar( { a: true } );',
'styles' => '.mw-test-bar { content: "style"; }',
- )),
+ ) ),
'test.baz' => new ResourceLoaderTestModule( array(
'script' => 'mw.test.baz( { a: true } );',
'styles' => '.mw-test-baz { content: "style"; }',
- )),
+ ) ),
'test.quux' => new ResourceLoaderTestModule( array(
'script' => 'mw.test.baz( { token: 123 } );',
'styles' => '/* pref-animate=off */ .mw-icon { transition: none; }',
'group' => 'private',
- )),
+ ) ),
'test.raw' => new ResourceLoaderTestModule( array(
'script' => 'mw.test.baz( { token: 123 } );',
'isRaw' => true,
- )),
+ ) ),
'test.noscript' => new ResourceLoaderTestModule( array(
'styles' => '.mw-test-noscript { content: "style"; }',
'group' => 'noscript',
- )),
+ ) ),
'test.group.bar' => new ResourceLoaderTestModule( array(
'styles' => '.mw-group-bar { content: "style"; }',
'group' => 'bar',
- )),
+ ) ),
'test.group.foo' => new ResourceLoaderTestModule( array(
'styles' => '.mw-group-foo { content: "style"; }',
'group' => 'foo',
- )),
+ ) ),
) );
$links = $method->invokeArgs( $out, $args );
- // Strip comments to avoid variation due to wgDBname in WikiID and cache key
- $actualHtml = preg_replace( '#/\*[^*]+\*/#', '', $links['html'] );
+ $actualHtml = implode( "\n", $links['html'] );
$this->assertEquals( $expectedHtml, $actualHtml );
}
+
+ /**
+ * @dataProvider provideVaryHeaders
+ * @covers OutputPage::addVaryHeader
+ * @covers OutputPage::getVaryHeader
+ * @covers OutputPage::getXVO
+ */
+ public function testVaryHeaders( $calls, $vary, $xvo ) {
+ // get rid of default Vary fields
+ $outputPage = $this->getMockBuilder( 'OutputPage' )
+ ->setConstructorArgs( array( new RequestContext() ) )
+ ->setMethods( array( 'getCacheVaryCookies' ) )
+ ->getMock();
+ $outputPage->expects( $this->any() )
+ ->method( 'getCacheVaryCookies' )
+ ->will( $this->returnValue( array() ) );
+ TestingAccessWrapper::newFromObject( $outputPage )->mVaryHeader = array();
+
+ foreach ( $calls as $call ) {
+ call_user_func_array( array( $outputPage, 'addVaryHeader' ), $call );
+ }
+ $this->assertEquals( $vary, $outputPage->getVaryHeader(), 'Vary:' );
+ $this->assertEquals( $xvo, $outputPage->getXVO(), 'X-Vary-Options:' );
+ }
+
+ public function provideVaryHeaders() {
+ // note: getXVO() automatically adds Vary: Cookie
+ return array(
+ array( // single header
+ array(
+ array( 'Cookie' ),
+ ),
+ 'Vary: Cookie',
+ 'X-Vary-Options: Cookie',
+ ),
+ array( // non-unique headers
+ array(
+ array( 'Cookie' ),
+ array( 'Accept-Language' ),
+ array( 'Cookie' ),
+ ),
+ 'Vary: Cookie, Accept-Language',
+ 'X-Vary-Options: Cookie,Accept-Language',
+ ),
+ array( // two headers with single options
+ array(
+ array( 'Cookie', array( 'string-contains=phpsessid' ) ),
+ array( 'Accept-Language', array( 'string-contains=en' ) ),
+ ),
+ 'Vary: Cookie, Accept-Language',
+ 'X-Vary-Options: Cookie;string-contains=phpsessid,Accept-Language;string-contains=en',
+ ),
+ array( // one header with multiple options
+ array(
+ array( 'Cookie', array( 'string-contains=phpsessid', 'string-contains=userId' ) ),
+ ),
+ 'Vary: Cookie',
+ 'X-Vary-Options: Cookie;string-contains=phpsessid;string-contains=userId',
+ ),
+ array( // Duplicate option
+ array(
+ array( 'Cookie', array( 'string-contains=phpsessid' ) ),
+ array( 'Cookie', array( 'string-contains=phpsessid' ) ),
+ array( 'Accept-Language', array( 'string-contains=en', 'string-contains=en' ) ),
+
+
+ ),
+ 'Vary: Cookie, Accept-Language',
+ 'X-Vary-Options: Cookie;string-contains=phpsessid,Accept-Language;string-contains=en',
+ ),
+ array( // Same header, different options
+ array(
+ array( 'Cookie', array( 'string-contains=phpsessid' ) ),
+ array( 'Cookie', array( 'string-contains=userId' ) ),
+ ),
+ 'Vary: Cookie',
+ 'X-Vary-Options: Cookie;string-contains=phpsessid;string-contains=userId',
+ ),
+ );
+ }
}
/**
* MessageBlobStore that doesn't do anything
*/
class NullMessageBlobStore extends MessageBlobStore {
- public function get ( ResourceLoader $resourceLoader, $modules, $lang ) {
+ public function get( ResourceLoader $resourceLoader, $modules, $lang ) {
return array();
}
- public function insertMessageBlob ( $name, ResourceLoaderModule $module, $lang ) {
+ public function insertMessageBlob( $name, ResourceLoaderModule $module, $lang ) {
return false;
}
- public function updateModule ( $name, ResourceLoaderModule $module, $lang ) {
+ public function updateModule( $name, ResourceLoaderModule $module, $lang ) {
return;
}
- public function updateMessage ( $key ) {
+ public function updateMessage( $key ) {
}
public function clear() {
}
}
-
diff --git a/tests/phpunit/includes/PrefixSearchTest.php b/tests/phpunit/includes/PrefixSearchTest.php
index d63541b7..afd10e9a 100644
--- a/tests/phpunit/includes/PrefixSearchTest.php
+++ b/tests/phpunit/includes/PrefixSearchTest.php
@@ -6,6 +6,11 @@
class PrefixSearchTest extends MediaWikiLangTestCase {
public function addDBData() {
+ if ( !$this->isWikitextNS( NS_MAIN ) ) {
+ // tests are skipped if NS_MAIN is not wikitext
+ return;
+ }
+
$this->insertPage( 'Sandbox' );
$this->insertPage( 'Bar' );
$this->insertPage( 'Example' );
diff --git a/tests/phpunit/includes/SanitizerTest.php b/tests/phpunit/includes/SanitizerTest.php
index c615c460..d3dc512b 100644
--- a/tests/phpunit/includes/SanitizerTest.php
+++ b/tests/phpunit/includes/SanitizerTest.php
@@ -6,6 +6,11 @@
*/
class SanitizerTest extends MediaWikiTestCase {
+ protected function tearDown() {
+ MWTidy::destroySingleton();
+ parent::tearDown();
+ }
+
/**
* @covers Sanitizer::decodeCharReferences
*/
@@ -93,9 +98,7 @@ class SanitizerTest extends MediaWikiTestCase {
* @param bool $escaped Whether sanitizer let the tag in or escape it (ie: '&lt;video&gt;')
*/
public function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) {
- $this->setMwGlobals( array(
- 'wgUseTidy' => false
- ) );
+ MWTidy::setInstance( false );
if ( $escaped ) {
$this->assertEquals( "&lt;$tag&gt;",
@@ -157,7 +160,7 @@ class SanitizerTest extends MediaWikiTestCase {
* @covers Sanitizer::removeHTMLtags
*/
public function testRemoveHTMLtags( $input, $output, $msg = null ) {
- $GLOBALS['wgUseTidy'] = false;
+ MWTidy::setInstance( false );
$this->assertEquals( $output, Sanitizer::removeHTMLtags( $input ), $msg );
}
@@ -360,5 +363,4 @@ class SanitizerTest extends MediaWikiTestCase {
array( '&lt;script&gt;foo&lt;/script&gt;', '<script>foo</script>' ),
);
}
-
}
diff --git a/tests/phpunit/includes/SanitizerValidateEmailTest.php b/tests/phpunit/includes/SanitizerValidateEmailTest.php
index 14911f04..f47e74e2 100644
--- a/tests/phpunit/includes/SanitizerValidateEmailTest.php
+++ b/tests/phpunit/includes/SanitizerValidateEmailTest.php
@@ -5,7 +5,7 @@
* @todo all test methods in this class should be refactored and...
* use a single test method and a single data provider...
*/
-class SanitizerValidateEmailTest extends MediaWikiTestCase {
+class SanitizerValidateEmailTest extends PHPUnit_Framework_TestCase {
private function checkEmail( $addr, $expected = true, $msg = '' ) {
if ( $msg == '' ) {
diff --git a/tests/phpunit/includes/StatusTest.php b/tests/phpunit/includes/StatusTest.php
index c013f4fc..291ed315 100644
--- a/tests/phpunit/includes/StatusTest.php
+++ b/tests/phpunit/includes/StatusTest.php
@@ -372,7 +372,7 @@ class StatusTest extends MediaWikiLangTestCase {
);
$status = new Status();
- $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
+ $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
$testCases['1MessageWarning'] = array(
$status,
"<fooBar!>",
@@ -449,7 +449,7 @@ class StatusTest extends MediaWikiLangTestCase {
// );
$status = new Status();
- $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
+ $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
$testCases['1MessageWarning'] = array(
$status,
array( 'foo', 'bar' ),
diff --git a/tests/phpunit/includes/TemplateParserTest.php b/tests/phpunit/includes/TemplateParserTest.php
index 81854ff3..3b37f4a4 100644
--- a/tests/phpunit/includes/TemplateParserTest.php
+++ b/tests/phpunit/includes/TemplateParserTest.php
@@ -57,7 +57,20 @@ class TemplateParserTest extends MediaWikiTestCase {
array(),
false,
'RuntimeException',
- )
+ ),
+ array(
+ 'has_partial',
+ array(
+ 'planet' => 'world',
+ ),
+ "Partial hello world!\n in here\n",
+ ),
+ array(
+ 'bad_partial',
+ array(),
+ false,
+ 'Exception',
+ ),
);
}
}
diff --git a/tests/phpunit/includes/TestingAccessWrapper.php b/tests/phpunit/includes/TestingAccessWrapper.php
index 84c0f9b5..63d89719 100644
--- a/tests/phpunit/includes/TestingAccessWrapper.php
+++ b/tests/phpunit/includes/TestingAccessWrapper.php
@@ -34,16 +34,42 @@ class TestingAccessWrapper {
return $methodReflection->invokeArgs( $this->object, $args );
}
- public function __set( $name, $value ) {
+ /**
+ * ReflectionClass::getProperty() fails if the private property is defined
+ * in a parent class. This works more like ReflectionClass::getMethod().
+ */
+ private function getProperty( $name ) {
$classReflection = new ReflectionClass( $this->object );
- $propertyReflection = $classReflection->getProperty( $name );
+ try {
+ return $classReflection->getProperty( $name );
+ } catch ( ReflectionException $ex ) {
+ while ( true ) {
+ $classReflection = $classReflection->getParentClass();
+ if ( !$classReflection ) {
+ throw $ex;
+ }
+ try {
+ $propertyReflection = $classReflection->getProperty( $name );
+ } catch ( ReflectionException $ex2 ) {
+ continue;
+ }
+ if ( $propertyReflection->isPrivate() ) {
+ return $propertyReflection;
+ } else {
+ throw $ex;
+ }
+ }
+ }
+ }
+
+ public function __set( $name, $value ) {
+ $propertyReflection = $this->getProperty( $name );
$propertyReflection->setAccessible( true );
$propertyReflection->setValue( $this->object, $value );
}
public function __get( $name ) {
- $classReflection = new ReflectionClass( $this->object );
- $propertyReflection = $classReflection->getProperty( $name );
+ $propertyReflection = $this->getProperty( $name );
$propertyReflection->setAccessible( true );
return $propertyReflection->getValue( $this->object );
}
diff --git a/tests/phpunit/includes/TestingAccessWrapperTest.php b/tests/phpunit/includes/TestingAccessWrapperTest.php
index 7e5b91a1..fc54afae 100644
--- a/tests/phpunit/includes/TestingAccessWrapperTest.php
+++ b/tests/phpunit/includes/TestingAccessWrapperTest.php
@@ -14,18 +14,36 @@ class TestingAccessWrapperTest extends MediaWikiTestCase {
function testGetProperty() {
$this->assertSame( 1, $this->wrapped->property );
+ $this->assertSame( 42, $this->wrapped->privateProperty );
+ $this->assertSame( 9000, $this->wrapped->privateParentProperty );
}
function testSetProperty() {
$this->wrapped->property = 10;
$this->assertSame( 10, $this->wrapped->property );
$this->assertSame( 10, $this->raw->getProperty() );
+
+ $this->wrapped->privateProperty = 11;
+ $this->assertSame( 11, $this->wrapped->privateProperty );
+ $this->assertSame( 11, $this->raw->getPrivateProperty() );
+
+ $this->wrapped->privateParentProperty = 12;
+ $this->assertSame( 12, $this->wrapped->privateParentProperty );
+ $this->assertSame( 12, $this->raw->getPrivateParentProperty() );
}
function testCallMethod() {
$this->wrapped->incrementPropertyValue();
$this->assertSame( 2, $this->wrapped->property );
$this->assertSame( 2, $this->raw->getProperty() );
+
+ $this->wrapped->incrementPrivatePropertyValue();
+ $this->assertSame( 43, $this->wrapped->privateProperty );
+ $this->assertSame( 43, $this->raw->getPrivateProperty() );
+
+ $this->wrapped->incrementPrivateParentPropertyValue();
+ $this->assertSame( 9001, $this->wrapped->privateParentProperty );
+ $this->assertSame( 9001, $this->raw->getPrivateParentProperty() );
}
function testCallMethodTwoArgs() {
diff --git a/tests/phpunit/includes/TitleArrayFromResultTest.php b/tests/phpunit/includes/TitleArrayFromResultTest.php
index 0f7069ae..6654a5b6 100644
--- a/tests/phpunit/includes/TitleArrayFromResultTest.php
+++ b/tests/phpunit/includes/TitleArrayFromResultTest.php
@@ -4,7 +4,7 @@
* @author Adam Shorland
* @covers TitleArrayFromResult
*/
-class TitleArrayFromResultTest extends MediaWikiTestCase {
+class TitleArrayFromResultTest extends PHPUnit_Framework_TestCase {
private function getMockResultWrapper( $row = null, $numRows = 1 ) {
$resultWrapper = $this->getMockBuilder( 'ResultWrapper' )
diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php
index 022c7d53..f588ed63 100644
--- a/tests/phpunit/includes/TitlePermissionTest.php
+++ b/tests/phpunit/includes/TitlePermissionTest.php
@@ -664,7 +664,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
$this->setTitle( NS_MAIN, "test page" );
$this->title->mTitleProtection['permission'] = '';
$this->title->mTitleProtection['user'] = $this->user->getID();
- $this->title->mTitleProtection['expiry'] = wfGetDB( DB_SLAVE )->getInfinity();
+ $this->title->mTitleProtection['expiry'] = 'infinity';
$this->title->mTitleProtection['reason'] = 'test';
$this->title->mCascadeRestriction = false;
@@ -753,8 +753,14 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
$prev = time();
$now = time() + 120;
$this->user->mBlockedby = $this->user->getId();
- $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(),
- 'no reason given', $prev + 3600, 1, 0 );
+ $this->user->mBlock = new Block( array(
+ 'address' => '127.0.8.1',
+ 'by' => $this->user->getId(),
+ 'reason' => 'no reason given',
+ 'timestamp' => $prev + 3600,
+ 'auto' => true,
+ 'expiry' => 0
+ ) );
$this->user->mBlock->mTimestamp = 0;
$this->assertEquals( array( array( 'autoblockedtext',
'[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
@@ -770,8 +776,14 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
global $wgLocalTZoffset;
$wgLocalTZoffset = -60;
$this->user->mBlockedby = $this->user->getName();
- $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(),
- 'no reason given', $now, 0, 10 );
+ $this->user->mBlock = new Block( array(
+ 'address' => '127.0.8.1',
+ 'by' => $this->user->getId(),
+ 'reason' => 'no reason given',
+ 'timestamp' => $now,
+ 'auto' => false,
+ 'expiry' => 10,
+ ) );
$this->assertEquals( array( array( 'blockedtext',
'[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php
index d55f958b..a2c6f23d 100644
--- a/tests/phpunit/includes/TitleTest.php
+++ b/tests/phpunit/includes/TitleTest.php
@@ -1,6 +1,7 @@
<?php
/**
+ * @group Database
* @group Title
*/
class TitleTest extends MediaWikiTestCase {
@@ -79,22 +80,22 @@ class TitleTest extends MediaWikiTestCase {
public static function provideInvalidSecureAndSplit() {
return array(
- array( '' ),
- array( ':' ),
- array( '__ __' ),
- array( ' __ ' ),
+ array( '', 'title-invalid-empty' ),
+ array( ':', 'title-invalid-empty' ),
+ array( '__ __', 'title-invalid-empty' ),
+ array( ' __ ', 'title-invalid-empty' ),
// Bad characters forbidden regardless of wgLegalTitleChars
- array( 'A [ B' ),
- array( 'A ] B' ),
- array( 'A { B' ),
- array( 'A } B' ),
- array( 'A < B' ),
- array( 'A > B' ),
- array( 'A | B' ),
+ array( 'A [ B', 'title-invalid-characters' ),
+ array( 'A ] B', 'title-invalid-characters' ),
+ array( 'A { B', 'title-invalid-characters' ),
+ array( 'A } B', 'title-invalid-characters' ),
+ array( 'A < B', 'title-invalid-characters' ),
+ array( 'A > B', 'title-invalid-characters' ),
+ array( 'A | B', 'title-invalid-characters' ),
// URL encoding
- array( 'A%20B' ),
- array( 'A%23B' ),
- array( 'A%2523B' ),
+ array( 'A%20B', 'title-invalid-characters' ),
+ array( 'A%23B', 'title-invalid-characters' ),
+ array( 'A%2523B', 'title-invalid-characters' ),
// XML/HTML character entity references
// Note: Commented out because they are not marked invalid by the PHP test as
// Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first.
@@ -102,29 +103,30 @@ class TitleTest extends MediaWikiTestCase {
//'A &#233; B',
//'A &#x00E9; B',
// Subject of NS_TALK does not roundtrip to NS_MAIN
- array( 'Talk:File:Example.svg' ),
+ array( 'Talk:File:Example.svg', 'title-invalid-talk-namespace' ),
// Directory navigation
- array( '.' ),
- array( '..' ),
- array( './Sandbox' ),
- array( '../Sandbox' ),
- array( 'Foo/./Sandbox' ),
- array( 'Foo/../Sandbox' ),
- array( 'Sandbox/.' ),
- array( 'Sandbox/..' ),
+ array( '.', 'title-invalid-relative' ),
+ array( '..', 'title-invalid-relative' ),
+ array( './Sandbox', 'title-invalid-relative' ),
+ array( '../Sandbox', 'title-invalid-relative' ),
+ array( 'Foo/./Sandbox', 'title-invalid-relative' ),
+ array( 'Foo/../Sandbox', 'title-invalid-relative' ),
+ array( 'Sandbox/.', 'title-invalid-relative' ),
+ array( 'Sandbox/..', 'title-invalid-relative' ),
// Tilde
- array( 'A ~~~ Name' ),
- array( 'A ~~~~ Signature' ),
- array( 'A ~~~~~ Timestamp' ),
- array( str_repeat( 'x', 256 ) ),
+ array( 'A ~~~ Name', 'title-invalid-magic-tilde' ),
+ array( 'A ~~~~ Signature', 'title-invalid-magic-tilde' ),
+ array( 'A ~~~~~ Timestamp', 'title-invalid-magic-tilde' ),
+ // Length
+ array( str_repeat( 'x', 256 ), 'title-invalid-too-long' ),
// Namespace prefix without actual title
- array( 'Talk:' ),
- array( 'Talk:#' ),
- array( 'Category: ' ),
- array( 'Category: #bar' ),
+ array( 'Talk:', 'title-invalid-empty' ),
+ array( 'Talk:#', 'title-invalid-empty' ),
+ array( 'Category: ', 'title-invalid-empty' ),
+ array( 'Category: #bar', 'title-invalid-empty' ),
// interwiki prefix
- array( 'localtestiw: Talk: # anchor' ),
- array( 'localtestiw: Talk:' )
+ array( 'localtestiw: Talk: # anchor', 'title-invalid-empty' ),
+ array( 'localtestiw: Talk:', 'title-invalid-empty' )
);
}
@@ -143,7 +145,7 @@ class TitleTest extends MediaWikiTestCase {
}
)
)
- ));
+ ) );
}
/**
@@ -163,9 +165,14 @@ class TitleTest extends MediaWikiTestCase {
* @dataProvider provideInvalidSecureAndSplit
* @note This mainly tests MediaWikiTitleCodec::parseTitle().
*/
- public function testSecureAndSplitInvalid( $text ) {
+ public function testSecureAndSplitInvalid( $text, $expectedErrorMessage ) {
$this->secureAndSplitGlobals();
- $this->assertNull( Title::newFromText( $text ), "Invalid: $text" );
+ try {
+ Title::newFromTextThrow( $text ); // should throw
+ $this->assertTrue( false, "Invalid: $text" );
+ } catch ( MalformedTitleException $ex ) {
+ $this->assertEquals( $expectedErrorMessage, $ex->getErrorMessage(), "Invalid: $text" );
+ }
}
public static function provideConvertByteClassToUnicodeClass() {
@@ -631,4 +638,26 @@ class TitleTest extends MediaWikiTestCase {
$title = Title::makeTitle( NS_MAIN, 'Interwiki link', '', 'externalwiki' );
$this->assertTrue( $title->isAlwaysKnown() );
}
+
+ /**
+ * @covers Title::exists
+ */
+ public function testExists() {
+ $title = Title::makeTitle( NS_PROJECT, 'New page' );
+ $linkCache = LinkCache::singleton();
+
+ $article = new Article( $title );
+ $page = $article->getPage();
+ $page->doEditContent( new WikitextContent( 'Some [[link]]' ), 'summary' );
+
+ // Tell Title it doesn't know whether it exists
+ $title->mArticleID = -1;
+
+ // Tell the link cache it doesn't exists when it really does
+ $linkCache->clearLink( $title );
+ $linkCache->addBadLinkObj( $title );
+
+ $this->assertEquals( false, $title->exists(), 'exists() should rely on link cache unless GAID_FOR_UPDATE is used' );
+ $this->assertEquals( true, $title->exists( Title::GAID_FOR_UPDATE ), 'exists() should re-query database when GAID_FOR_UPDATE is used' );
+ }
}
diff --git a/tests/phpunit/includes/UserTest.php b/tests/phpunit/includes/UserTest.php
index b74a7ead..77132bbb 100644
--- a/tests/phpunit/includes/UserTest.php
+++ b/tests/phpunit/includes/UserTest.php
@@ -307,9 +307,30 @@ class UserTest extends MediaWikiTestCase {
*/
public function testCheckPasswordValidity() {
$this->setMwGlobals( array(
- 'wgMinimalPasswordLength' => 6,
- 'wgMaximalPasswordLength' => 30,
+ 'wgPasswordPolicy' => array(
+ 'policies' => array(
+ 'sysop' => array(
+ 'MinimalPasswordLength' => 8,
+ 'MinimumPasswordLengthToLogin' => 1,
+ 'PasswordCannotMatchUsername' => 1,
+ ),
+ 'default' => array(
+ 'MinimalPasswordLength' => 6,
+ 'PasswordCannotMatchUsername' => true,
+ 'PasswordCannotMatchBlacklist' => true,
+ 'MaximalPasswordLength' => 30,
+ ),
+ ),
+ 'checks' => array(
+ 'MinimalPasswordLength' => 'PasswordPolicyChecks::checkMinimalPasswordLength',
+ 'MinimumPasswordLengthToLogin' => 'PasswordPolicyChecks::checkMinimumPasswordLengthToLogin',
+ 'PasswordCannotMatchUsername' => 'PasswordPolicyChecks::checkPasswordCannotMatchUsername',
+ 'PasswordCannotMatchBlacklist' => 'PasswordPolicyChecks::checkPasswordCannotMatchBlacklist',
+ 'MaximalPasswordLength' => 'PasswordPolicyChecks::checkMaximalPasswordLength',
+ ),
+ ),
) );
+
$user = User::newFromName( 'Useruser' );
// Sanity
$this->assertTrue( $user->isValidPassword( 'Password1234' ) );
@@ -425,4 +446,109 @@ class UserTest extends MediaWikiTestCase {
$this->assertFalse( $user->isLoggedIn() );
$this->assertTrue( $user->isAnon() );
}
+
+ /**
+ * @covers User::checkAndSetTouched
+ */
+ public function testCheckAndSetTouched() {
+ $user = TestingAccessWrapper::newFromObject( User::newFromName( 'UTSysop' ) );
+ $this->assertTrue( $user->isLoggedIn() );
+
+ $touched = $user->getDBTouched();
+ $this->assertTrue(
+ $user->checkAndSetTouched(), "checkAndSetTouched() succeded" );
+ $this->assertGreaterThan(
+ $touched, $user->getDBTouched(), "user_touched increased with casOnTouched()" );
+
+ $touched = $user->getDBTouched();
+ $this->assertTrue(
+ $user->checkAndSetTouched(), "checkAndSetTouched() succeded #2" );
+ $this->assertGreaterThan(
+ $touched, $user->getDBTouched(), "user_touched increased with casOnTouched() #2" );
+ }
+
+ public static function setExtendedLoginCookieDataProvider() {
+ $data = array();
+ $now = time();
+
+ $secondsInDay = 86400;
+
+ // Arbitrary durations, in units of days, to ensure it chooses the
+ // right one. There is a 5-minute grace period (see testSetExtendedLoginCookie)
+ // to work around slow tests, since we're not currently mocking time() for PHP.
+
+ $durationOne = $secondsInDay * 5;
+ $durationTwo = $secondsInDay * 29;
+ $durationThree = $secondsInDay * 17;
+
+ // If $wgExtendedLoginCookieExpiration is null, then the expiry passed to
+ // set cookie is time() + $wgCookieExpiration
+ $data[] = array(
+ null,
+ $durationOne,
+ $now + $durationOne,
+ );
+
+ // If $wgExtendedLoginCookieExpiration isn't null, then the expiry passed to
+ // set cookie is $now + $wgExtendedLoginCookieExpiration
+ $data[] = array(
+ $durationTwo,
+ $durationThree,
+ $now + $durationTwo,
+ );
+
+ return $data;
+ }
+
+ /**
+ * @dataProvider setExtendedLoginCookieDataProvider
+ * @covers User::getRequest
+ * @covers User::setCookie
+ * @backupGlobals enabled
+ */
+ public function testSetExtendedLoginCookie(
+ $extendedLoginCookieExpiration,
+ $cookieExpiration,
+ $expectedExpiry
+ ) {
+ $this->setMwGlobals( array(
+ 'wgExtendedLoginCookieExpiration' => $extendedLoginCookieExpiration,
+ 'wgCookieExpiration' => $cookieExpiration,
+ ) );
+
+ $response = $this->getMock( 'WebResponse' );
+ $setcookieSpy = $this->any();
+ $response->expects( $setcookieSpy )
+ ->method( 'setcookie' );
+
+ $request = new MockWebRequest( $response );
+ $user = new UserProxy( User::newFromSession( $request ) );
+ $user->setExtendedLoginCookie( 'name', 'value', true );
+
+ $setcookieInvocations = $setcookieSpy->getInvocations();
+ $setcookieInvocation = end( $setcookieInvocations );
+ $actualExpiry = $setcookieInvocation->parameters[ 2 ];
+
+ // TODO: ± 300 seconds compensates for
+ // slow-running tests. However, the dependency on the time
+ // function should be removed. This requires some way
+ // to mock/isolate User->setExtendedLoginCookie's call to time()
+ $this->assertEquals( $expectedExpiry, $actualExpiry, '', 300 );
+ }
+}
+
+class UserProxy extends User {
+
+ /**
+ * @var User
+ */
+ protected $user;
+
+ public function __construct( User $user ) {
+ $this->user = $user;
+ }
+
+ public function setExtendedLoginCookie( $name, $value, $secure ) {
+ $this->user->setExtendedLoginCookie( $name, $value, $secure );
+ }
}
diff --git a/tests/phpunit/includes/WikiMapTest.php b/tests/phpunit/includes/WikiMapTest.php
new file mode 100644
index 00000000..9233416c
--- /dev/null
+++ b/tests/phpunit/includes/WikiMapTest.php
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * @covers WikiMap
+ */
+
+class WikiMapTest extends MediaWikiLangTestCase {
+
+ public function setUp() {
+ parent::setUp();
+
+ $conf = new SiteConfiguration();
+ $conf->settings = array(
+ 'wgServer' => array(
+ 'enwiki' => 'http://en.example.org',
+ 'ruwiki' => '//ru.example.org',
+ ),
+ 'wgArticlePath' => array(
+ 'enwiki' => '/w/$1',
+ 'ruwiki' => '/wiki/$1',
+ ),
+ );
+ $conf->suffixes = array( 'wiki' );
+ $this->setMwGlobals( array(
+ 'wgConf' => $conf,
+ ) );
+ }
+
+ public function provideGetWiki() {
+ $enwiki = new WikiReference( 'wiki', 'en', 'http://en.example.org', '/w/$1' );
+ $ruwiki = new WikiReference( 'wiki', 'ru', '//ru.example.org', '/wiki/$1' );
+
+ return array(
+ 'unknown' => array( false, 'xyzzy' ),
+ 'enwiki' => array( $enwiki, 'enwiki' ),
+ 'ruwiki' => array( $ruwiki, 'ruwiki' ),
+ );
+ }
+
+ /**
+ * @dataProvider provideGetWiki
+ */
+ public function testGetWiki( $expected, $wikiId ) {
+ $this->assertEquals( $expected, WikiMap::getWiki( $wikiId ) );
+ }
+
+ public function provideGetWikiName() {
+ return array(
+ 'unknown' => array( 'xyzzy', 'xyzzy' ),
+ 'enwiki' => array( 'en.example.org', 'enwiki' ),
+ 'ruwiki' => array( 'ru.example.org', 'ruwiki' ),
+ );
+ }
+
+ /**
+ * @dataProvider provideGetWikiName
+ */
+ public function testGetWikiName( $expected, $wikiId ) {
+ $this->assertEquals( $expected, WikiMap::getWikiName( $wikiId ) );
+ }
+
+ public function provideMakeForeignLink() {
+ return array(
+ 'unknown' => array( false, 'xyzzy', 'Foo' ),
+ 'enwiki' => array( '<a class="external" rel="nofollow" href="http://en.example.org/w/Foo">Foo</a>', 'enwiki', 'Foo', ),
+ 'ruwiki' => array( '<a class="external" rel="nofollow" href="//ru.example.org/wiki/%D0%A4%D1%83">вар</a>', 'ruwiki', 'Фу', 'вар' ),
+ );
+ }
+
+ /**
+ * @dataProvider provideMakeForeignLink
+ */
+ public function testMakeForeignLink( $expected, $wikiId, $page, $text = null ) {
+ $this->assertEquals( $expected, WikiMap::makeForeignLink( $wikiId, $page, $text ) );
+ }
+
+ public function provideForeignUserLink() {
+ return array(
+ 'unknown' => array( false, 'xyzzy', 'Foo' ),
+ 'enwiki' => array( '<a class="external" rel="nofollow" href="http://en.example.org/w/User:Foo">User:Foo</a>', 'enwiki', 'Foo', ),
+ 'ruwiki' => array( '<a class="external" rel="nofollow" href="//ru.example.org/wiki/User:%D0%A4%D1%83">вар</a>', 'ruwiki', 'Фу', 'вар' ),
+ );
+ }
+
+ /**
+ * @dataProvider provideForeignUserLink
+ */
+ public function testForeignUserLink( $expected, $wikiId, $user, $text = null ) {
+ $this->assertEquals( $expected, WikiMap::foreignUserLink( $wikiId, $user, $text ) );
+ }
+
+ public function provideGetForeignURL() {
+ return array(
+ 'unknown' => array( false, 'xyzzy', 'Foo' ),
+ 'enwiki' => array( 'http://en.example.org/w/Foo', 'enwiki', 'Foo', ),
+ 'ruwiki with fragement' => array( '//ru.example.org/wiki/%D0%A4%D1%83#%D0%B2%D0%B0%D1%80', 'ruwiki', 'Фу', 'вар' ),
+ );
+ }
+
+ /**
+ * @dataProvider provideGetForeignURL
+ */
+ public function testGetForeignURL( $expected, $wikiId, $page, $fragment = null ) {
+ $this->assertEquals( $expected, WikiMap::getForeignURL( $wikiId, $page, $fragment ) );
+ }
+
+}
+
diff --git a/tests/phpunit/includes/WikiReferenceTest.php b/tests/phpunit/includes/WikiReferenceTest.php
new file mode 100644
index 00000000..4fe2e855
--- /dev/null
+++ b/tests/phpunit/includes/WikiReferenceTest.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * @covers WikiReference
+ */
+
+class WikiReferenceTest extends PHPUnit_Framework_TestCase {
+
+ public function provideGetDisplayName() {
+ return array(
+ 'http' => array( 'foo.bar', 'http://foo.bar' ),
+ 'https' => array( 'foo.bar', 'http://foo.bar' ),
+
+ // apparently, this is the expected behavior
+ 'invalid' => array( 'purple kittens', 'purple kittens' ),
+ );
+ }
+
+ /**
+ * @dataProvider provideGetDisplayName
+ */
+ public function testGetDisplayName( $expected, $canonicalServer ) {
+ $reference = new WikiReference( 'wiki', 'xx', $canonicalServer, '/wiki/$1' );
+ $this->assertEquals( $expected, $reference->getDisplayName() );
+ }
+
+ public function testGetCanonicalServer() {
+ $reference = new WikiReference( 'wiki', 'xx', 'https://acme.com', '/wiki/$1', '//acme.com' );
+ $this->assertEquals( 'https://acme.com', $reference->getCanonicalServer() );
+ }
+
+ public function provideGetCanonicalUrl() {
+ return array(
+ 'no fragement' => array( 'https://acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', null ),
+ 'empty fragement' => array( 'https://acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', '' ),
+ 'fragment' => array( 'https://acme.com/wiki/Foo#Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar' ),
+ 'double fragment' => array( 'https://acme.com/wiki/Foo#Bar%23Xus', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar#Xus' ),
+ 'escaped fragement' => array( 'https://acme.com/wiki/Foo%23Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo#Bar', null ),
+ 'empty path' => array( 'https://acme.com/Foo', 'https://acme.com', '//acme.com', '/$1', 'Foo', null ),
+ );
+ }
+
+ /**
+ * @dataProvider provideGetCanonicalUrl
+ */
+ public function testGetCanonicalUrl( $expected, $canonicalServer, $server, $path, $page, $fragmentId ) {
+ $reference = new WikiReference( 'wiki', 'xx', $canonicalServer, $path, $server );
+ $this->assertEquals( $expected, $reference->getCanonicalUrl( $page, $fragmentId ) );
+ }
+
+ /**
+ * @dataProvider provideGetCanonicalUrl
+ * @note getUrl is an alias for getCanonicalUrl
+ */
+ public function testGetUrl( $expected, $canonicalServer, $server, $path, $page, $fragmentId ) {
+ $reference = new WikiReference( 'wiki', 'xx', $canonicalServer, $path, $server );
+ $this->assertEquals( $expected, $reference->getUrl( $page, $fragmentId ) );
+ }
+
+ public function provideGetFullUrl() {
+ return array(
+ 'no fragement' => array( '//acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', null ),
+ 'empty fragement' => array( '//acme.com/wiki/Foo', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', '' ),
+ 'fragment' => array( '//acme.com/wiki/Foo#Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar' ),
+ 'double fragment' => array( '//acme.com/wiki/Foo#Bar%23Xus', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo', 'Bar#Xus' ),
+ 'escaped fragement' => array( '//acme.com/wiki/Foo%23Bar', 'https://acme.com', '//acme.com', '/wiki/$1', 'Foo#Bar', null ),
+ 'empty path' => array( '//acme.com/Foo', 'https://acme.com', '//acme.com', '/$1', 'Foo', null ),
+ );
+ }
+
+ /**
+ * @dataProvider provideGetFullUrl
+ */
+ public function testGetFullUrl( $expected, $canonicalServer, $server, $path, $page, $fragmentId ) {
+ $reference = new WikiReference( 'wiki', 'xx', $canonicalServer, $path, $server );
+ $this->assertEquals( $expected, $reference->getFullUrl( $page, $fragmentId ) );
+ }
+
+}
+
diff --git a/tests/phpunit/includes/XmlJsTest.php b/tests/phpunit/includes/XmlJsTest.php
index 0dbb0109..21819b7e 100644
--- a/tests/phpunit/includes/XmlJsTest.php
+++ b/tests/phpunit/includes/XmlJsTest.php
@@ -3,7 +3,7 @@
/**
* @group Xml
*/
-class XmlJs extends MediaWikiTestCase {
+class XmlJs extends PHPUnit_Framework_TestCase {
/**
* @covers XmlJsCode::__construct
diff --git a/tests/phpunit/includes/XmlTest.php b/tests/phpunit/includes/XmlTest.php
index 382e3d89..bea338de 100644
--- a/tests/phpunit/includes/XmlTest.php
+++ b/tests/phpunit/includes/XmlTest.php
@@ -154,7 +154,7 @@ class XmlTest extends MediaWikiTestCase {
'<label for="year">From year (and earlier):</label> ' .
'<input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> ' .
'<label for="month">From month (and earlier):</label> ' .
- '<select id="month" name="month" class="mw-month-selector">' .
+ '<select name="month" id="month" class="mw-month-selector">' .
'<option value="-1">all</option>' . "\n" .
'<option value="1">January</option>' . "\n" .
'<option value="2" selected="">February</option>' . "\n" .
@@ -175,7 +175,7 @@ class XmlTest extends MediaWikiTestCase {
'<label for="year">From year (and earlier):</label> ' .
'<input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> ' .
'<label for="month">From month (and earlier):</label> ' .
- '<select id="month" name="month" class="mw-month-selector">' .
+ '<select name="month" id="month" class="mw-month-selector">' .
'<option value="-1">all</option>' . "\n" .
'<option value="1">January</option>' . "\n" .
'<option value="2">February</option>' . "\n" .
@@ -209,7 +209,7 @@ class XmlTest extends MediaWikiTestCase {
'<label for="year">From year (and earlier):</label> ' .
'<input id="year" maxlength="4" size="7" type="number" name="year" /> ' .
'<label for="month">From month (and earlier):</label> ' .
- '<select id="month" name="month" class="mw-month-selector">' .
+ '<select name="month" id="month" class="mw-month-selector">' .
'<option value="-1">all</option>' . "\n" .
'<option value="1">January</option>' . "\n" .
'<option value="2">February</option>' . "\n" .
diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php
index d98eec6a..575efd6d 100644
--- a/tests/phpunit/includes/api/ApiBlockTest.php
+++ b/tests/phpunit/includes/api/ApiBlockTest.php
@@ -53,7 +53,7 @@ class ApiBlockTest extends ApiTestCase {
'action' => 'block',
'user' => 'UTApiBlockee',
'reason' => 'Some reason',
- 'token' => $tokens['blocktoken'] ), null, false, self::$users['sysop']->user );
+ 'token' => $tokens['blocktoken'] ), null, false, self::$users['sysop']->getUser() );
$block = Block::newFromTarget( 'UTApiBlockee' );
@@ -68,7 +68,7 @@ class ApiBlockTest extends ApiTestCase {
* @expectedException UsageException
* @expectedExceptionMessage The token parameter must be set
*/
- public function testBlockingActionWithNoToken( ) {
+ public function testBlockingActionWithNoToken() {
$this->doApiRequest(
array(
'action' => 'block',
@@ -77,7 +77,7 @@ class ApiBlockTest extends ApiTestCase {
),
null,
false,
- self::$users['sysop']->user
+ self::$users['sysop']->getUser()
);
}
}
diff --git a/tests/phpunit/includes/api/ApiEditPageTest.php b/tests/phpunit/includes/api/ApiEditPageTest.php
index 3179a452..61a8ad11 100644
--- a/tests/phpunit/includes/api/ApiEditPageTest.php
+++ b/tests/phpunit/includes/api/ApiEditPageTest.php
@@ -27,9 +27,14 @@ class ApiEditPageTest extends ApiTestCase {
$wgExtraNamespaces[12312] = 'Dummy';
$wgExtraNamespaces[12313] = 'Dummy_talk';
+ $wgExtraNamespaces[12314] = 'DummyNonText';
+ $wgExtraNamespaces[12315] = 'DummyNonText_talk';
$wgNamespaceContentModels[12312] = "testing";
+ $wgNamespaceContentModels[12314] = "testing-nontext";
+
$wgContentHandlers["testing"] = 'DummyContentHandlerForTesting';
+ $wgContentHandlers["testing-nontext"] = 'DummyNonTextContentHandler';
MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
$wgContLang->resetNamespaces(); # reset namespace cache
@@ -96,33 +101,6 @@ class ApiEditPageTest extends ApiTestCase {
);
}
- public function testNonTextEdit() {
- $name = 'Dummy:ApiEditPageTest_testNonTextEdit';
- $data = serialize( 'some bla bla text' );
-
- // -- test new page --------------------------------------------
- $apiResult = $this->doApiRequestWithToken( array(
- 'action' => 'edit',
- 'title' => $name,
- 'text' => $data, ) );
- $apiResult = $apiResult[0];
-
- // Validate API result data
- $this->assertArrayHasKey( 'edit', $apiResult );
- $this->assertArrayHasKey( 'result', $apiResult['edit'] );
- $this->assertEquals( 'Success', $apiResult['edit']['result'] );
-
- $this->assertArrayHasKey( 'new', $apiResult['edit'] );
- $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] );
-
- $this->assertArrayHasKey( 'pageid', $apiResult['edit'] );
-
- // validate resulting revision
- $page = WikiPage::factory( Title::newFromText( $name ) );
- $this->assertEquals( "testing", $page->getContentModel() );
- $this->assertEquals( $data, $page->getContent()->serialize() );
- }
-
/**
* @return array
*/
@@ -240,7 +218,7 @@ class ApiEditPageTest extends ApiTestCase {
'section' => 'new',
'text' => 'test',
'summary' => 'header',
- ));
+ ) );
$this->assertEquals( 'Success', $re['edit']['result'] );
// Check the page text is correct
@@ -257,7 +235,7 @@ class ApiEditPageTest extends ApiTestCase {
'section' => 'new',
'text' => 'test',
'summary' => 'header',
- ));
+ ) );
$this->assertEquals( 'Success', $re2['edit']['result'] );
$text = WikiPage::factory( Title::newFromText( $name ) )
@@ -284,18 +262,18 @@ class ApiEditPageTest extends ApiTestCase {
// base edit for content
$page->doEditContent( new WikitextContent( "Foo" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $page, '20120101000000' );
$baseTime = $page->getRevision()->getTimestamp();
// base edit for redirect
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $rpage, '20120101000000' );
// conflicting edit to redirect
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ),
- "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user );
+ "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
$this->forceRevisionDate( $rpage, '20120101020202' );
// try to save edit, following the redirect
@@ -306,7 +284,7 @@ class ApiEditPageTest extends ApiTestCase {
'basetimestamp' => $baseTime,
'section' => 'new',
'redirect' => true,
- ), null, self::$users['sysop']->user );
+ ), null, self::$users['sysop']->getUser() );
$this->assertEquals( 'Success', $re['edit']['result'],
"no problems expected when following redirect" );
@@ -330,18 +308,18 @@ class ApiEditPageTest extends ApiTestCase {
// base edit for content
$page->doEditContent( new WikitextContent( "Foo" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $page, '20120101000000' );
$baseTime = $page->getRevision()->getTimestamp();
// base edit for redirect
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $rpage, '20120101000000' );
// conflicting edit to redirect
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ),
- "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user );
+ "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
$this->forceRevisionDate( $rpage, '20120101020202' );
// try to save edit, following the redirect but without creating a section
@@ -352,7 +330,7 @@ class ApiEditPageTest extends ApiTestCase {
'text' => 'nix bar!',
'basetimestamp' => $baseTime,
'redirect' => true,
- ), null, self::$users['sysop']->user );
+ ), null, self::$users['sysop']->getUser() );
$this->fail( 'redirect-appendonly error expected' );
} catch ( UsageException $ex ) {
@@ -372,13 +350,13 @@ class ApiEditPageTest extends ApiTestCase {
// base edit
$page->doEditContent( new WikitextContent( "Foo" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $page, '20120101000000' );
$baseTime = $page->getRevision()->getTimestamp();
// conflicting edit
$page->doEditContent( new WikitextContent( "Foo bar" ),
- "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user );
+ "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
$this->forceRevisionDate( $page, '20120101020202' );
// try to save edit, expect conflict
@@ -388,7 +366,7 @@ class ApiEditPageTest extends ApiTestCase {
'title' => $name,
'text' => 'nix bar!',
'basetimestamp' => $baseTime,
- ), null, self::$users['sysop']->user );
+ ), null, self::$users['sysop']->getUser() );
$this->fail( 'edit conflict expected' );
} catch ( UsageException $ex ) {
@@ -411,13 +389,13 @@ class ApiEditPageTest extends ApiTestCase {
// base edit
$page->doEditContent( new WikitextContent( "Foo" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $page, '20120101000000' );
$baseTime = $page->getRevision()->getTimestamp();
// conflicting edit
$page->doEditContent( new WikitextContent( "Foo bar" ),
- "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user );
+ "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
$this->forceRevisionDate( $page, '20120101020202' );
// try to save edit, expect no conflict
@@ -427,7 +405,7 @@ class ApiEditPageTest extends ApiTestCase {
'text' => 'nix bar!',
'basetimestamp' => $baseTime,
'section' => 'new',
- ), null, self::$users['sysop']->user );
+ ), null, self::$users['sysop']->getUser() );
$this->assertEquals( 'Success', $re['edit']['result'],
"no edit conflict expected here" );
@@ -454,17 +432,17 @@ class ApiEditPageTest extends ApiTestCase {
// base edit for content
$page->doEditContent( new WikitextContent( "Foo" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $page, '20120101000000' );
// base edit for redirect
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
- "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
+ "testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
$this->forceRevisionDate( $rpage, '20120101000000' );
// new edit to content
$page->doEditContent( new WikitextContent( "Foo bar" ),
- "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user );
+ "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
$this->forceRevisionDate( $rpage, '20120101020202' );
// try to save edit; should work, following the redirect.
@@ -474,7 +452,7 @@ class ApiEditPageTest extends ApiTestCase {
'text' => 'nix bar!',
'section' => 'new',
'redirect' => true,
- ), null, self::$users['sysop']->user );
+ ), null, self::$users['sysop']->getUser() );
$this->assertEquals( 'Success', $re['edit']['result'],
"no edit conflict expected here" );
@@ -493,4 +471,45 @@ class ApiEditPageTest extends ApiTestCase {
$page->clear();
}
+
+ public function testCheckDirectApiEditingDisallowed_forNonTextContent() {
+ $this->setExpectedException(
+ 'UsageException',
+ 'Direct editing via API is not supported for content model testing used by Dummy:ApiEditPageTest_nonTextPageEdit'
+ );
+
+ $this->doApiRequestWithToken( array(
+ 'action' => 'edit',
+ 'title' => 'Dummy:ApiEditPageTest_nonTextPageEdit',
+ 'text' => '{"animals":["kittens!"]}'
+ ) );
+ }
+
+ public function testSupportsDirectApiEditing_withContentHandlerOverride() {
+ $name = 'DummyNonText:ApiEditPageTest_testNonTextEdit';
+ $data = serialize( 'some bla bla text' );
+
+ $result = $this->doApiRequestWithToken( array(
+ 'action' => 'edit',
+ 'title' => $name,
+ 'text' => $data,
+ ) );
+
+ $apiResult = $result[0];
+
+ // Validate API result data
+ $this->assertArrayHasKey( 'edit', $apiResult );
+ $this->assertArrayHasKey( 'result', $apiResult['edit'] );
+ $this->assertEquals( 'Success', $apiResult['edit']['result'] );
+
+ $this->assertArrayHasKey( 'new', $apiResult['edit'] );
+ $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] );
+
+ $this->assertArrayHasKey( 'pageid', $apiResult['edit'] );
+
+ // validate resulting revision
+ $page = WikiPage::factory( Title::newFromText( $name ) );
+ $this->assertEquals( "testing-nontext", $page->getContentModel() );
+ $this->assertEquals( $data, $page->getContent()->serialize() );
+ }
}
diff --git a/tests/phpunit/includes/api/ApiLoginTest.php b/tests/phpunit/includes/api/ApiLoginTest.php
index 88a99e9b..7dfd14f3 100644
--- a/tests/phpunit/includes/api/ApiLoginTest.php
+++ b/tests/phpunit/includes/api/ApiLoginTest.php
@@ -23,7 +23,7 @@ class ApiLoginTest extends ApiTestCase {
global $wgServer;
$user = self::$users['sysop'];
- $user->user->logOut();
+ $user->getUser()->logOut();
if ( !isset( $wgServer ) ) {
$this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
@@ -68,7 +68,7 @@ class ApiLoginTest extends ApiTestCase {
}
$user = self::$users['sysop'];
- $user->user->logOut();
+ $user->getUser()->logOut();
$ret = $this->doApiRequest( array(
"action" => "login",
diff --git a/tests/phpunit/includes/api/ApiMainTest.php b/tests/phpunit/includes/api/ApiMainTest.php
index e8ef1804..94b741dc 100644
--- a/tests/phpunit/includes/api/ApiMainTest.php
+++ b/tests/phpunit/includes/api/ApiMainTest.php
@@ -71,7 +71,7 @@ class ApiMainTest extends ApiTestCase {
new FauxRequest( array( 'action' => 'query', 'meta' => 'siteinfo' ) )
);
$modules = $api->getModuleManager()->getNamesWithClasses();
- foreach( $modules as $name => $class ) {
+ foreach ( $modules as $name => $class ) {
$this->assertArrayHasKey(
$class,
$classes,
@@ -79,4 +79,173 @@ class ApiMainTest extends ApiTestCase {
);
}
}
+
+ /**
+ * Test HTTP precondition headers
+ *
+ * @covers ApiMain::checkConditionalRequestHeaders
+ * @dataProvider provideCheckConditionalRequestHeaders
+ * @param array $headers HTTP headers
+ * @param array $conditions Return data for ApiBase::getConditionalRequestData
+ * @param int $status Expected response status
+ * @param bool $post Request is a POST
+ */
+ public function testCheckConditionalRequestHeaders( $headers, $conditions, $status, $post = false ) {
+ $request = new FauxRequest( array( 'action' => 'query', 'meta' => 'siteinfo' ), $post );
+ $request->setHeaders( $headers );
+ $request->response()->statusHeader( 200 ); // Why doesn't it default?
+
+ $api = new ApiMain( $request );
+ $priv = TestingAccessWrapper::newFromObject( $api );
+ $priv->mInternalMode = false;
+
+ $module = $this->getMockBuilder( 'ApiBase' )
+ ->setConstructorArgs( array( $api, 'mock' ) )
+ ->setMethods( array( 'getConditionalRequestData' ) )
+ ->getMockForAbstractClass();
+ $module->expects( $this->any() )
+ ->method( 'getConditionalRequestData' )
+ ->will( $this->returnCallback( function ( $condition ) use ( $conditions ) {
+ return isset( $conditions[$condition] ) ? $conditions[$condition] : null;
+ } ) );
+
+ $ret = $priv->checkConditionalRequestHeaders( $module );
+
+ $this->assertSame( $status, $request->response()->getStatusCode() );
+ $this->assertSame( $status === 200, $ret );
+ }
+
+ public static function provideCheckConditionalRequestHeaders() {
+ $now = time();
+
+ return array(
+ // Non-existing from module is ignored
+ array( array( 'If-None-Match' => '"foo", "bar"' ), array(), 200 ),
+ array( array( 'If-Modified-Since' => 'Tue, 18 Aug 2015 00:00:00 GMT' ), array(), 200 ),
+
+ // No headers
+ array(
+ array(),
+ array(
+ 'etag' => '""',
+ 'last-modified' => '20150815000000',
+ ),
+ 200
+ ),
+
+ // Basic If-None-Match
+ array( array( 'If-None-Match' => '"foo", "bar"' ), array( 'etag' => '"bar"' ), 304 ),
+ array( array( 'If-None-Match' => '"foo", "bar"' ), array( 'etag' => '"baz"' ), 200 ),
+ array( array( 'If-None-Match' => '"foo"' ), array( 'etag' => 'W/"foo"' ), 304 ),
+ array( array( 'If-None-Match' => 'W/"foo"' ), array( 'etag' => '"foo"' ), 304 ),
+ array( array( 'If-None-Match' => 'W/"foo"' ), array( 'etag' => 'W/"foo"' ), 304 ),
+
+ // Pointless, but supported
+ array( array( 'If-None-Match' => '*' ), array(), 304 ),
+
+ // Basic If-Modified-Since
+ array( array( 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now ) ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 304 ),
+ array( array( 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now ) ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now ) ), 304 ),
+ array( array( 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now ) ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now + 1 ) ), 200 ),
+
+ // If-Modified-Since ignored when If-None-Match is given too
+ array( array( 'If-None-Match' => '""', 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now ) ),
+ array( 'etag' => '"x"', 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 200 ),
+ array( array( 'If-None-Match' => '""', 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now ) ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 304 ),
+
+ // Ignored for POST
+ array( array( 'If-None-Match' => '"foo", "bar"' ), array( 'etag' => '"bar"' ), 200, true ),
+ array( array( 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now ) ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 200, true ),
+
+ // Other date formats allowed by the RFC
+ array( array( 'If-Modified-Since' => gmdate( 'l, d-M-y H:i:s', $now ) . ' GMT' ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 304 ),
+ array( array( 'If-Modified-Since' => gmdate( 'D M j H:i:s Y', $now ) ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 304 ),
+
+ // Old browser extension to HTTP/1.0
+ array( array( 'If-Modified-Since' => wfTimestamp( TS_RFC2822, $now ) . '; length=123' ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 304 ),
+
+ // Invalid date formats should be ignored
+ array( array( 'If-Modified-Since' => gmdate( 'Y-m-d H:i:s', $now ) . ' GMT' ),
+ array( 'last-modified' => wfTimestamp( TS_MW, $now - 1 ) ), 200 ),
+ );
+ }
+
+ /**
+ * Test conditional headers output
+ * @dataProvider provideConditionalRequestHeadersOutput
+ * @param array $conditions Return data for ApiBase::getConditionalRequestData
+ * @param array $headers Expected output headers
+ * @param bool $isError $isError flag
+ * @param bool $post Request is a POST
+ */
+ public function testConditionalRequestHeadersOutput( $conditions, $headers, $isError = false, $post = false ) {
+ $request = new FauxRequest( array( 'action' => 'query', 'meta' => 'siteinfo' ), $post );
+ $response = $request->response();
+
+ $api = new ApiMain( $request );
+ $priv = TestingAccessWrapper::newFromObject( $api );
+ $priv->mInternalMode = false;
+
+ $module = $this->getMockBuilder( 'ApiBase' )
+ ->setConstructorArgs( array( $api, 'mock' ) )
+ ->setMethods( array( 'getConditionalRequestData' ) )
+ ->getMockForAbstractClass();
+ $module->expects( $this->any() )
+ ->method( 'getConditionalRequestData' )
+ ->will( $this->returnCallback( function ( $condition ) use ( $conditions ) {
+ return isset( $conditions[$condition] ) ? $conditions[$condition] : null;
+ } ) );
+ $priv->mModule = $module;
+
+ $priv->sendCacheHeaders( $isError );
+
+ foreach ( array( 'Last-Modified', 'ETag' ) as $header ) {
+ $this->assertEquals(
+ isset( $headers[$header] ) ? $headers[$header] : null,
+ $response->getHeader( $header ),
+ $header
+ );
+ }
+ }
+
+ public static function provideConditionalRequestHeadersOutput() {
+ return array(
+ array(
+ array(),
+ array()
+ ),
+ array(
+ array( 'etag' => '"foo"' ),
+ array( 'ETag' => '"foo"' )
+ ),
+ array(
+ array( 'last-modified' => '20150818000102' ),
+ array( 'Last-Modified' => 'Tue, 18 Aug 2015 00:01:02 GMT' )
+ ),
+ array(
+ array( 'etag' => '"foo"', 'last-modified' => '20150818000102' ),
+ array( 'ETag' => '"foo"', 'Last-Modified' => 'Tue, 18 Aug 2015 00:01:02 GMT' )
+ ),
+ array(
+ array( 'etag' => '"foo"', 'last-modified' => '20150818000102' ),
+ array(),
+ true,
+ ),
+ array(
+ array( 'etag' => '"foo"', 'last-modified' => '20150818000102' ),
+ array(),
+ false,
+ true,
+ ),
+ );
+ }
+
}
diff --git a/tests/phpunit/includes/api/ApiMessageTest.php b/tests/phpunit/includes/api/ApiMessageTest.php
index 6c3ce60d..08a984eb 100644
--- a/tests/phpunit/includes/api/ApiMessageTest.php
+++ b/tests/phpunit/includes/api/ApiMessageTest.php
@@ -14,9 +14,13 @@ class ApiMessageTest extends MediaWikiTestCase {
$msg = TestingAccessWrapper::newFromObject( $msg );
$msg2 = TestingAccessWrapper::newFromObject( $msg2 );
- foreach ( array( 'interface', 'useDatabase', 'title' ) as $key ) {
- $this->assertSame( $msg->$key, $msg2->$key, $key );
- }
+ $this->assertSame( $msg->interface, $msg2->interface, 'interface' );
+ $this->assertSame( $msg->useDatabase, $msg2->useDatabase, 'useDatabase' );
+ $this->assertSame(
+ $msg->title ? $msg->title->getFullText() : null,
+ $msg2->title ? $msg2->title->getFullText() : null,
+ 'title'
+ );
}
/**
@@ -30,6 +34,11 @@ class ApiMessageTest extends MediaWikiTestCase {
$this->assertEquals( 'code', $msg2->getApiCode() );
$this->assertEquals( array( 'data' ), $msg2->getApiData() );
+ $msg2 = unserialize( serialize( $msg2 ) );
+ $this->compareMessages( $msg, $msg2 );
+ $this->assertEquals( 'code', $msg2->getApiCode() );
+ $this->assertEquals( array( 'data' ), $msg2->getApiData() );
+
$msg = new Message( array( 'foo', 'bar' ), array( 'baz' ) );
$msg2 = new ApiMessage( array( array( 'foo', 'bar' ), 'baz' ), 'code', array( 'data' ) );
$this->compareMessages( $msg, $msg2 );
@@ -63,6 +72,11 @@ class ApiMessageTest extends MediaWikiTestCase {
$this->assertEquals( 'code', $msg2->getApiCode() );
$this->assertEquals( array( 'data' ), $msg2->getApiData() );
+ $msg2 = unserialize( serialize( $msg2 ) );
+ $this->compareMessages( $msg, $msg2 );
+ $this->assertEquals( 'code', $msg2->getApiCode() );
+ $this->assertEquals( array( 'data' ), $msg2->getApiData() );
+
$msg = new RawMessage( 'foo', array( 'baz' ) );
$msg2 = new ApiRawMessage( array( 'foo', 'baz' ), 'code', array( 'data' ) );
$this->compareMessages( $msg, $msg2 );
diff --git a/tests/phpunit/includes/api/ApiQueryAllPagesTest.php b/tests/phpunit/includes/api/ApiQueryAllPagesTest.php
index 124988f3..0ac00eea 100644
--- a/tests/phpunit/includes/api/ApiQueryAllPagesTest.php
+++ b/tests/phpunit/includes/api/ApiQueryAllPagesTest.php
@@ -13,9 +13,11 @@ class ApiQueryAllPagesTest extends ApiTestCase {
}
/**
- * @todo give this test a real name explaining what is being tested here
+ *Test bug 25702
+ *Prefixes of API search requests are not handled with case sensitivity and may result
+ *in wrong search results
*/
- public function testBug25702() {
+ public function testPrefixNormalizationSearchBug() {
$title = Title::newFromText( 'Category:Template:xyz' );
$page = WikiPage::factory( $title );
$page->doEdit( 'Some text', 'inserting content' );
diff --git a/tests/phpunit/includes/api/ApiResultTest.php b/tests/phpunit/includes/api/ApiResultTest.php
index f0d84552..2f31677e 100644
--- a/tests/phpunit/includes/api/ApiResultTest.php
+++ b/tests/phpunit/includes/api/ApiResultTest.php
@@ -181,6 +181,19 @@ class ApiResultTest extends MediaWikiTestCase {
);
}
+ ApiResult::setValue( $arr, null, NAN, ApiResult::NO_VALIDATE );
+
+ try {
+ ApiResult::setValue( $arr, null, NAN, ApiResult::NO_SIZE_CHECK );
+ $this->fail( 'Expected exception not thrown' );
+ } catch ( InvalidArgumentException $ex ) {
+ $this->assertSame(
+ 'Cannot add non-finite floats to ApiResult',
+ $ex->getMessage(),
+ 'Expected exception'
+ );
+ }
+
$arr = array();
$result2 = new ApiResult( 8388608 );
$result2->addValue( null, 'foo', 'bar' );
@@ -408,6 +421,19 @@ class ApiResultTest extends MediaWikiTestCase {
);
}
+ $result->addValue( null, null, NAN, ApiResult::NO_VALIDATE );
+
+ try {
+ $result->addValue( null, null, NAN, ApiResult::NO_SIZE_CHECK );
+ $this->fail( 'Expected exception not thrown' );
+ } catch ( InvalidArgumentException $ex ) {
+ $this->assertSame(
+ 'Cannot add non-finite floats to ApiResult',
+ $ex->getMessage(),
+ 'Expected exception'
+ );
+ }
+
$result->reset();
$result->addParsedLimit( 'foo', 12 );
$this->assertSame( array(
@@ -444,6 +470,12 @@ class ApiResultTest extends MediaWikiTestCase {
$result->removeValue( null, 'foo' );
$this->assertTrue( $result->addValue( null, 'foo', '1' ) );
+ $result = new ApiResult( 10 );
+ $obj = new ApiResultTestSerializableObject( 'ok' );
+ $obj->foobar = 'foobaz';
+ $this->assertTrue( $result->addValue( null, 'foo', $obj ) );
+ $this->assertSame( 2, $result->getSize() );
+
$result = new ApiResult( 8388608 );
$result2 = new ApiResult( 8388608 );
$result2->addValue( null, 'foo', 'bar' );
@@ -674,6 +706,10 @@ class ApiResultTest extends MediaWikiTestCase {
ApiResult::META_TYPE => 'BCkvp',
ApiResult::META_KVP_KEY_NAME => 'key',
),
+ 'kvpmerge' => array( 'x' => 'a', 'y' => array( 'b' ), 'z' => array( 'c' => 'd' ),
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_MERGE => true,
+ ),
'emptyDefault' => array( '_dummy' => 1 ),
'emptyAssoc' => array( '_dummy' => 1, ApiResult::META_TYPE => 'assoc' ),
'_dummy' => 1,
@@ -858,6 +894,13 @@ class ApiResultTest extends MediaWikiTestCase {
ApiResult::META_TYPE => 'assoc',
ApiResult::META_KVP_KEY_NAME => 'key',
),
+ 'kvpmerge' => array(
+ 'x' => 'a',
+ 'y' => array( 'b', ApiResult::META_TYPE => 'array' ),
+ 'z' => array( 'c' => 'd', ApiResult::META_TYPE => 'assoc' ),
+ ApiResult::META_TYPE => 'assoc',
+ ApiResult::META_KVP_MERGE => true,
+ ),
'emptyDefault' => array( '_dummy' => 1, ApiResult::META_TYPE => 'array' ),
'emptyAssoc' => array( '_dummy' => 1, ApiResult::META_TYPE => 'assoc' ),
'_dummy' => 1,
@@ -871,8 +914,12 @@ class ApiResultTest extends MediaWikiTestCase {
array( 'Types' => array( 'AssocAsObject' => true ) ),
(object)array(
'defaultArray' => array( 'b', 'c', 'a', ApiResult::META_TYPE => 'array' ),
- 'defaultAssoc' => (object)array( 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult::META_TYPE => 'assoc' ),
- 'defaultAssoc2' => (object)array( 2 => 'a', 3 => 'b', 0 => 'c', ApiResult::META_TYPE => 'assoc' ),
+ 'defaultAssoc' => (object)array( 'x' => 'a',
+ 1 => 'b', 0 => 'c', ApiResult::META_TYPE => 'assoc'
+ ),
+ 'defaultAssoc2' => (object)array( 2 => 'a', 3 => 'b',
+ 0 => 'c', ApiResult::META_TYPE => 'assoc'
+ ),
'array' => array( 'a', 'c', 'b', ApiResult::META_TYPE => 'array' ),
'BCarray' => array( 'a', 'c', 'b', ApiResult::META_TYPE => 'array' ),
'BCassoc' => (object)array( 'a', 'b', 'c', ApiResult::META_TYPE => 'assoc' ),
@@ -885,6 +932,13 @@ class ApiResultTest extends MediaWikiTestCase {
ApiResult::META_TYPE => 'assoc',
ApiResult::META_KVP_KEY_NAME => 'key',
),
+ 'kvpmerge' => (object)array(
+ 'x' => 'a',
+ 'y' => array( 'b', ApiResult::META_TYPE => 'array' ),
+ 'z' => (object)array( 'c' => 'd', ApiResult::META_TYPE => 'assoc' ),
+ ApiResult::META_TYPE => 'assoc',
+ ApiResult::META_KVP_MERGE => true,
+ ),
'emptyDefault' => array( '_dummy' => 1, ApiResult::META_TYPE => 'array' ),
'emptyAssoc' => (object)array( '_dummy' => 1, ApiResult::META_TYPE => 'assoc' ),
'_dummy' => 1,
@@ -916,6 +970,13 @@ class ApiResultTest extends MediaWikiTestCase {
ApiResult::META_TYPE => 'array',
ApiResult::META_KVP_KEY_NAME => 'key',
),
+ 'kvpmerge' => array(
+ $kvp( 'name', 'x', 'value', 'a' ),
+ $kvp( 'name', 'y', 'value', array( 'b', ApiResult::META_TYPE => 'array' ) ),
+ array( 'name' => 'z', 'c' => 'd', ApiResult::META_TYPE => 'assoc', ApiResult::META_PRESERVE_KEYS => array( 'name' ) ),
+ ApiResult::META_TYPE => 'array',
+ ApiResult::META_KVP_MERGE => true,
+ ),
'emptyDefault' => array( '_dummy' => 1, ApiResult::META_TYPE => 'array' ),
'emptyAssoc' => array( '_dummy' => 1, ApiResult::META_TYPE => 'assoc' ),
'_dummy' => 1,
@@ -947,6 +1008,13 @@ class ApiResultTest extends MediaWikiTestCase {
ApiResult::META_TYPE => 'array',
ApiResult::META_KVP_KEY_NAME => 'key',
),
+ 'kvpmerge' => array(
+ $kvp( 'name', 'x', '*', 'a' ),
+ $kvp( 'name', 'y', '*', array( 'b', ApiResult::META_TYPE => 'array' ) ),
+ array( 'name' => 'z', 'c' => 'd', ApiResult::META_TYPE => 'assoc', ApiResult::META_PRESERVE_KEYS => array( 'name' ) ),
+ ApiResult::META_TYPE => 'array',
+ ApiResult::META_KVP_MERGE => true,
+ ),
'emptyDefault' => array( '_dummy' => 1, ApiResult::META_TYPE => 'array' ),
'emptyAssoc' => array( '_dummy' => 1, ApiResult::META_TYPE => 'assoc' ),
'_dummy' => 1,
@@ -960,8 +1028,12 @@ class ApiResultTest extends MediaWikiTestCase {
array( 'Types' => array( 'ArmorKVP' => 'name', 'AssocAsObject' => true ) ),
(object)array(
'defaultArray' => array( 'b', 'c', 'a', ApiResult::META_TYPE => 'array' ),
- 'defaultAssoc' => (object)array( 'x' => 'a', 1 => 'b', 0 => 'c', ApiResult::META_TYPE => 'assoc' ),
- 'defaultAssoc2' => (object)array( 2 => 'a', 3 => 'b', 0 => 'c', ApiResult::META_TYPE => 'assoc' ),
+ 'defaultAssoc' => (object)array( 'x' => 'a', 1 => 'b',
+ 0 => 'c', ApiResult::META_TYPE => 'assoc'
+ ),
+ 'defaultAssoc2' => (object)array( 2 => 'a', 3 => 'b',
+ 0 => 'c', ApiResult::META_TYPE => 'assoc'
+ ),
'array' => array( 'a', 'c', 'b', ApiResult::META_TYPE => 'array' ),
'BCarray' => array( 'a', 'c', 'b', ApiResult::META_TYPE => 'array' ),
'BCassoc' => (object)array( 'a', 'b', 'c', ApiResult::META_TYPE => 'assoc' ),
@@ -978,6 +1050,13 @@ class ApiResultTest extends MediaWikiTestCase {
ApiResult::META_TYPE => 'array',
ApiResult::META_KVP_KEY_NAME => 'key',
),
+ 'kvpmerge' => array(
+ (object)$kvp( 'name', 'x', 'value', 'a' ),
+ (object)$kvp( 'name', 'y', 'value', array( 'b', ApiResult::META_TYPE => 'array' ) ),
+ (object)array( 'name' => 'z', 'c' => 'd', ApiResult::META_TYPE => 'assoc', ApiResult::META_PRESERVE_KEYS => array( 'name' ) ),
+ ApiResult::META_TYPE => 'array',
+ ApiResult::META_KVP_MERGE => true,
+ ),
'emptyDefault' => array( '_dummy' => 1, ApiResult::META_TYPE => 'array' ),
'emptyAssoc' => (object)array( '_dummy' => 1, ApiResult::META_TYPE => 'assoc' ),
'_dummy' => 1,
@@ -1017,6 +1096,11 @@ class ApiResultTest extends MediaWikiTestCase {
(object)array( 'key' => 'x', 'value' => 'a' ),
(object)array( 'key' => 'y', 'value' => 'b' ),
),
+ 'kvpmerge' => array(
+ (object)array( 'name' => 'x', 'value' => 'a' ),
+ (object)array( 'name' => 'y', 'value' => array( 'b' ) ),
+ (object)array( 'name' => 'z', 'c' => 'd' ),
+ ),
'emptyDefault' => array(),
'emptyAssoc' => (object)array(),
'_dummy' => 1,
@@ -1127,13 +1211,84 @@ class ApiResultTest extends MediaWikiTestCase {
/**
* @covers ApiResult
*/
+ public function testAddMetadataToResultVars() {
+ $arr = array(
+ 'a' => "foo",
+ 'b' => false,
+ 'c' => 10,
+ 'sequential_numeric_keys' => array( 'a', 'b', 'c' ),
+ 'non_sequential_numeric_keys' => array( 'a', 'b', 4 => 'c' ),
+ 'string_keys' => array(
+ 'one' => 1,
+ 'two' => 2
+ ),
+ 'object_sequential_keys' => (object)array( 'a', 'b', 'c' ),
+ '_type' => "should be overwritten in result",
+ );
+ $this->assertSame( array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array(
+ 'a', 'b', 'c',
+ 'sequential_numeric_keys', 'non_sequential_numeric_keys',
+ 'string_keys', 'object_sequential_keys'
+ ),
+ ApiResult::META_BC_BOOLS => array( 'b' ),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 'a' => "foo",
+ 'b' => false,
+ 'c' => 10,
+ 'sequential_numeric_keys' => array(
+ ApiResult::META_TYPE => 'array',
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'value',
+ 0 => 'a',
+ 1 => 'b',
+ 2 => 'c',
+ ),
+ 'non_sequential_numeric_keys' => array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array( 0, 1, 4 ),
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 0 => 'a',
+ 1 => 'b',
+ 4 => 'c',
+ ),
+ 'string_keys' => array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array( 'one', 'two' ),
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 'one' => 1,
+ 'two' => 2,
+ ),
+ 'object_sequential_keys' => array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array( 0, 1, 2 ),
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 0 => 'a',
+ 1 => 'b',
+ 2 => 'c',
+ ),
+ ), ApiResult::addMetadataToResultVars( $arr ) );
+ }
+
+ /**
+ * @covers ApiResult
+ */
public function testDeprecatedFunctions() {
// Ignore ApiResult deprecation warnings during this test
set_error_handler( function ( $errno, $errstr ) use ( &$warnings ) {
if ( preg_match( '/Use of ApiResult::\S+ was deprecated in MediaWiki \d+.\d+\./', $errstr ) ) {
return true;
}
- if ( preg_match( '/Use of ApiMain to ApiResult::__construct was deprecated in MediaWiki \d+.\d+\./', $errstr ) ) {
+ if ( preg_match( '/Use of ApiMain to ApiResult::__construct ' .
+ 'was deprecated in MediaWiki \d+.\d+\./', $errstr ) ) {
return true;
}
return false;
@@ -1166,17 +1321,6 @@ class ApiResultTest extends MediaWikiTestCase {
),
'*' => 'content',
), $result->getData() );
- $result->setRawMode();
- $this->assertSame( array(
- 'foo' => array(
- 'bar' => array(
- '*' => 'content',
- ),
- ),
- '*' => 'content',
- '_element' => 'itn',
- '_subelements' => array( 'sub' ),
- ), $result->getData() );
$arr = array();
ApiResult::setContent( $arr, 'value' );
@@ -1451,7 +1595,8 @@ class ApiResultTest extends MediaWikiTestCase {
$result = new ApiResult( 8388608 );
$result->setMainForContinuation( $main );
- $result->beginContinuation( '||mock2', array_slice( $allModules, 0, 2 ), array( 'mock1', 'mock2' ) );
+ $result->beginContinuation( '||mock2', array_slice( $allModules, 0, 2 ),
+ array( 'mock1', 'mock2' ) );
try {
$result->setContinueParam( $allModules[1], 'm2continue', 1 );
$this->fail( 'Expected exception not thrown' );
@@ -1467,7 +1612,8 @@ class ApiResultTest extends MediaWikiTestCase {
$this->fail( 'Expected exception not thrown' );
} catch ( UnexpectedValueException $ex ) {
$this->assertSame(
- 'Module \'mocklist\' called ApiContinuationManager::addContinueParam but was not passed to ApiContinuationManager::__construct',
+ 'Module \'mocklist\' called ApiContinuationManager::addContinueParam ' .
+ 'but was not passed to ApiContinuationManager::__construct',
$ex->getMessage(),
'Expected exception'
);
@@ -1495,13 +1641,14 @@ class ApiResultTest extends MediaWikiTestCase {
try {
$arr = array();
- ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
+ ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
new ApiResultTestStringifiableObject()
) );
$this->fail( 'Expected exception not thrown' );
} catch ( UnexpectedValueException $ex ) {
$this->assertSame(
- 'ApiResultTestSerializableObject::serializeForApiResult() returned an object of class ApiResultTestStringifiableObject',
+ 'ApiResultTestSerializableObject::serializeForApiResult() ' .
+ 'returned an object of class ApiResultTestStringifiableObject',
$ex->getMessage(),
'Expected exception'
);
@@ -1509,18 +1656,19 @@ class ApiResultTest extends MediaWikiTestCase {
try {
$arr = array();
- ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject( NAN ) );
+ ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject( NAN ) );
$this->fail( 'Expected exception not thrown' );
} catch ( UnexpectedValueException $ex ) {
$this->assertSame(
- 'ApiResultTestSerializableObject::serializeForApiResult() returned an invalid value: Cannot add non-finite floats to ApiResult',
+ 'ApiResultTestSerializableObject::serializeForApiResult() ' .
+ 'returned an invalid value: Cannot add non-finite floats to ApiResult',
$ex->getMessage(),
'Expected exception'
);
}
$arr = array();
- ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
+ ApiResult::setValue( $arr, 'foo', new ApiResultTestSerializableObject(
array(
'one' => new ApiResultTestStringifiableObject( '1' ),
'two' => new ApiResultTestSerializableObject( 2 ),
diff --git a/tests/phpunit/includes/api/ApiRevisionDeleteTest.php b/tests/phpunit/includes/api/ApiRevisionDeleteTest.php
index b03836eb..362d647f 100644
--- a/tests/phpunit/includes/api/ApiRevisionDeleteTest.php
+++ b/tests/phpunit/includes/api/ApiRevisionDeleteTest.php
@@ -25,7 +25,7 @@ class ApiRevisionDeleteTest extends ApiTestCase {
}
public function testHidingRevisions() {
- $user = self::$users['sysop']->user;
+ $user = self::$users['sysop']->getUser();
$revid = array_shift( $this->revs );
$out = $this->doApiRequest( array(
'action' => 'revisiondelete',
@@ -80,7 +80,7 @@ class ApiRevisionDeleteTest extends ApiTestCase {
}
public function testUnhidingOutput() {
- $user = self::$users['sysop']->user;
+ $user = self::$users['sysop']->getUser();
$revid = array_shift( $this->revs );
// Hide revisions
$this->doApiRequest( array(
diff --git a/tests/phpunit/includes/api/ApiTestCase.php b/tests/phpunit/includes/api/ApiTestCase.php
index da62bb0a..21345ac1 100644
--- a/tests/phpunit/includes/api/ApiTestCase.php
+++ b/tests/phpunit/includes/api/ApiTestCase.php
@@ -105,6 +105,7 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
$wgRequest = new FauxRequest( $params, true, $session );
RequestContext::getMain()->setRequest( $wgRequest );
+ RequestContext::getMain()->setUser( $wgUser );
// set up local environment
$context = $this->apiContext->newTestContext( $wgRequest, $wgUser );
diff --git a/tests/phpunit/includes/api/ApiUnblockTest.php b/tests/phpunit/includes/api/ApiUnblockTest.php
index 2c2370a8..a374f094 100644
--- a/tests/phpunit/includes/api/ApiUnblockTest.php
+++ b/tests/phpunit/includes/api/ApiUnblockTest.php
@@ -16,7 +16,7 @@ class ApiUnblockTest extends ApiTestCase {
/**
* @expectedException UsageException
*/
- public function testWithNoToken( ) {
+ public function testWithNoToken() {
$this->doApiRequest(
array(
'action' => 'unblock',
@@ -25,7 +25,7 @@ class ApiUnblockTest extends ApiTestCase {
),
null,
false,
- self::$users['sysop']->user
+ self::$users['sysop']->getUser()
);
}
}
diff --git a/tests/phpunit/includes/api/ApiUploadTest.php b/tests/phpunit/includes/api/ApiUploadTest.php
index f74fc354..c852d72b 100644
--- a/tests/phpunit/includes/api/ApiUploadTest.php
+++ b/tests/phpunit/includes/api/ApiUploadTest.php
@@ -80,7 +80,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
try {
$this->doApiRequestWithToken( array(
'action' => 'upload',
- ), $session, self::$users['uploader']->user );
+ ), $session, self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$exception = true;
$this->assertEquals( "One of the parameters filekey, file, url, statuskey is required",
@@ -126,7 +126,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result, , ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user );
+ self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$exception = true;
}
@@ -165,7 +165,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
- $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user );
+ $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$this->assertContains( 'The file you submitted was empty', $e->getMessage() );
$exception = true;
@@ -215,7 +215,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user );
+ self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$exception = true;
}
@@ -232,7 +232,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result, , ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user ); // FIXME: leaks a temporary file
+ self::$users['uploader']->getUser() ); // FIXME: leaks a temporary file
} catch ( UsageException $e ) {
$exception = true;
}
@@ -286,7 +286,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user );
+ self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$exception = true;
}
@@ -311,7 +311,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user ); // FIXME: leaks a temporary file
+ self::$users['uploader']->getUser() ); // FIXME: leaks a temporary file
} catch ( UsageException $e ) {
$exception = true;
}
@@ -331,7 +331,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
*/
public function testUploadStash( $session ) {
$this->setMwGlobals( array(
- 'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere
+ 'wgUser' => self::$users['uploader']->getUser(), // @todo FIXME: still used somewhere
) );
$extension = 'png';
@@ -368,7 +368,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user ); // FIXME: leaks a temporary file
+ self::$users['uploader']->getUser() ); // FIXME: leaks a temporary file
} catch ( UsageException $e ) {
$exception = true;
}
@@ -397,7 +397,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user );
+ self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$exception = true;
}
@@ -415,7 +415,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
public function testUploadChunks( $session ) {
$this->setMwGlobals( array(
// @todo FIXME: still used somewhere
- 'wgUser' => self::$users['uploader']->user,
+ 'wgUser' => self::$users['uploader']->getUser(),
) );
$chunkSize = 1048576;
@@ -451,9 +451,9 @@ class ApiUploadTest extends ApiTestCaseUpload {
$chunkSessionKey = false;
$resultOffset = 0;
// Open the file:
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$handle = fopen( $filePath, "r" );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( $handle === false ) {
$this->markTestIncomplete( "could not open file: $filePath" );
@@ -461,9 +461,9 @@ class ApiUploadTest extends ApiTestCaseUpload {
while ( !feof( $handle ) ) {
// Get the current chunk
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$chunkData = fread( $handle, $chunkSize );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
// Upload the current chunk into the $_FILE object:
$this->fakeUploadChunk( 'chunk', 'blob', $mimeType, $chunkData );
@@ -473,7 +473,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
// Upload fist chunk ( and get the session key )
try {
list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user );
+ self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$this->markTestIncomplete( $e->getMessage() );
}
@@ -501,7 +501,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
// Upload current chunk
try {
list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user );
+ self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$this->markTestIncomplete( $e->getMessage() );
}
@@ -541,7 +541,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
$exception = false;
try {
list( $result ) = $this->doApiRequestWithToken( $params, $session,
- self::$users['uploader']->user );
+ self::$users['uploader']->getUser() );
} catch ( UsageException $e ) {
$exception = true;
}
diff --git a/tests/phpunit/includes/api/format/ApiFormatDumpTest.php b/tests/phpunit/includes/api/format/ApiFormatDumpTest.php
deleted file mode 100644
index c0f67f8d..00000000
--- a/tests/phpunit/includes/api/format/ApiFormatDumpTest.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @group API
- * @covers ApiFormatDump
- */
-class ApiFormatDumpTest extends ApiFormatTestBase {
-
- protected $printerName = 'dump';
-
- public static function provideGeneralEncoding() {
- // Sigh. Docs claim it's a boolean, but can have values 0, 1, or 2.
- // Fortunately wfIniGetBool does the right thing.
- if ( wfIniGetBool( 'xdebug.overload_var_dump' ) ) {
- return array(
- array( array(), 'Cannot test ApiFormatDump when xDebug overloads var_dump', array( 'SKIP' => true ) ),
- );
- }
-
- $warning = "\n [\"warnings\"]=>\n array(1) {\n [\"dump\"]=>\n array(1) {\n [\"*\"]=>\n" .
- " string(64) \"format=dump has been deprecated. Please use format=json instead.\"\n" .
- " }\n }";
-
- return array(
- // Basic types
- array( array( null ), "array(2) {{$warning}\n [0]=>\n NULL\n}\n" ),
- array( array( true ), "array(2) {{$warning}\n [0]=>\n string(0) \"\"\n}\n" ),
- array( array( false ), "array(1) {{$warning}\n}\n" ),
- array( array( true, ApiResult::META_BC_BOOLS => array( 0 ) ),
- "array(2) {{$warning}\n [0]=>\n bool(true)\n}\n" ),
- array( array( false, ApiResult::META_BC_BOOLS => array( 0 ) ),
- "array(2) {{$warning}\n [0]=>\n bool(false)\n}\n" ),
- array( array( 42 ), "array(2) {{$warning}\n [0]=>\n int(42)\n}\n" ),
- array( array( 42.5 ), "array(2) {{$warning}\n [0]=>\n float(42.5)\n}\n" ),
- array( array( 1e42 ), "array(2) {{$warning}\n [0]=>\n float(1.0E+42)\n}\n" ),
- array( array( 'foo' ), "array(2) {{$warning}\n [0]=>\n string(3) \"foo\"\n}\n" ),
- array( array( 'fóo' ), "array(2) {{$warning}\n [0]=>\n string(4) \"fóo\"\n}\n" ),
-
- // Arrays
- array( array( array() ), "array(2) {{$warning}\n [0]=>\n array(0) {\n }\n}\n" ),
- array( array( array( 1 ) ), "array(2) {{$warning}\n [0]=>\n array(1) {\n [0]=>\n int(1)\n }\n}\n" ),
- array( array( array( 'x' => 1 ) ), "array(2) {{$warning}\n [0]=>\n array(1) {\n [\"x\"]=>\n int(1)\n }\n}\n" ),
- array( array( array( 2 => 1 ) ), "array(2) {{$warning}\n [0]=>\n array(1) {\n [2]=>\n int(1)\n }\n}\n" ),
- array( array( (object)array() ), "array(2) {{$warning}\n [0]=>\n array(0) {\n }\n}\n" ),
- array( array( array( 1, ApiResult::META_TYPE => 'assoc' ) ), "array(2) {{$warning}\n [0]=>\n array(1) {\n [0]=>\n int(1)\n }\n}\n" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'array' ) ), "array(2) {{$warning}\n [0]=>\n array(1) {\n [0]=>\n int(1)\n }\n}\n" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'kvp' ) ), "array(2) {{$warning}\n [0]=>\n array(1) {\n [\"x\"]=>\n int(1)\n }\n}\n" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'BCkvp', ApiResult::META_KVP_KEY_NAME => 'key' ) ),
- "array(2) {{$warning}\n [0]=>\n array(1) {\n [0]=>\n array(2) {\n [\"key\"]=>\n string(1) \"x\"\n [\"*\"]=>\n int(1)\n }\n }\n}\n" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'BCarray' ) ), "array(2) {{$warning}\n [0]=>\n array(1) {\n [\"x\"]=>\n int(1)\n }\n}\n" ),
- array( array( array( 'a', 'b', ApiResult::META_TYPE => 'BCassoc' ) ), "array(2) {{$warning}\n [0]=>\n array(2) {\n [0]=>\n string(1) \"a\"\n [1]=>\n string(1) \"b\"\n }\n}\n" ),
-
- // Content
- array( array( 'content' => 'foo', ApiResult::META_CONTENT => 'content' ),
- "array(2) {{$warning}\n [\"*\"]=>\n string(3) \"foo\"\n}\n" ),
-
- // BC Subelements
- array( array( 'foo' => 'foo', ApiResult::META_BC_SUBELEMENTS => array( 'foo' ) ),
- "array(2) {{$warning}\n [\"foo\"]=>\n array(1) {\n [\"*\"]=>\n string(3) \"foo\"\n }\n}\n" ),
- );
- }
-
-}
diff --git a/tests/phpunit/includes/api/format/ApiFormatWddxTest.php b/tests/phpunit/includes/api/format/ApiFormatWddxTest.php
deleted file mode 100644
index 07111300..00000000
--- a/tests/phpunit/includes/api/format/ApiFormatWddxTest.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-/**
- * @group API
- * @covers ApiFormatWddx
- */
-class ApiFormatWddxTest extends ApiFormatTestBase {
-
- protected $printerName = 'wddx';
-
- public static function provideGeneralEncoding() {
- if ( ApiFormatWddx::useSlowPrinter() ) {
- return array(
- array( array(), 'Fast Wddx printer is unavailable', array( 'SKIP' => true ) )
- );
- }
- return self::provideEncoding();
- }
-
- public static function provideEncoding() {
- $p = '<wddxPacket version=\'1.0\'><header/><data><struct><var name=\'warnings\'><struct><var name=\'wddx\'><struct><var name=\'*\'><string>format=wddx has been deprecated. Please use format=json instead.</string></var></struct></var></struct></var>';
- $s = '</struct></data></wddxPacket>';
-
- return array(
- // Basic types
- array( array( null ), "{$p}<var name='0'><null/></var>{$s}" ),
- array( array( true ), "{$p}<var name='0'><string></string></var>{$s}" ),
- array( array( false ), "{$p}{$s}" ),
- array( array( true, ApiResult::META_BC_BOOLS => array( 0 ) ),
- "{$p}<var name='0'><boolean value='true'/></var>{$s}" ),
- array( array( false, ApiResult::META_BC_BOOLS => array( 0 ) ),
- "{$p}<var name='0'><boolean value='false'/></var>{$s}" ),
- array( array( 42 ), "{$p}<var name='0'><number>42</number></var>{$s}" ),
- array( array( 42.5 ), "{$p}<var name='0'><number>42.5</number></var>{$s}" ),
- array( array( 1e42 ), "{$p}<var name='0'><number>1.0E+42</number></var>{$s}" ),
- array( array( 'foo' ), "{$p}<var name='0'><string>foo</string></var>{$s}" ),
- array( array( 'fóo' ), "{$p}<var name='0'><string>fóo</string></var>{$s}" ),
-
- // Arrays and objects
- array( array( array() ), "{$p}<var name='0'><array length='0'></array></var>{$s}" ),
- array( array( array( 1 ) ), "{$p}<var name='0'><array length='1'><number>1</number></array></var>{$s}" ),
- array( array( array( 'x' => 1 ) ), "{$p}<var name='0'><struct><var name='x'><number>1</number></var></struct></var>{$s}" ),
- array( array( array( 2 => 1 ) ), "{$p}<var name='0'><struct><var name='2'><number>1</number></var></struct></var>{$s}" ),
- array( array( (object)array() ), "{$p}<var name='0'><struct></struct></var>{$s}" ),
- array( array( array( 1, ApiResult::META_TYPE => 'assoc' ) ), "{$p}<var name='0'><struct><var name='0'><number>1</number></var></struct></var>{$s}" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'array' ) ), "{$p}<var name='0'><array length='1'><number>1</number></array></var>{$s}" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'kvp' ) ), "{$p}<var name='0'><struct><var name='x'><number>1</number></var></struct></var>{$s}" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'BCkvp', ApiResult::META_KVP_KEY_NAME => 'key' ) ),
- "{$p}<var name='0'><array length='1'><struct><var name='key'><string>x</string></var><var name='*'><number>1</number></var></struct></array></var>{$s}" ),
- array( array( array( 'x' => 1, ApiResult::META_TYPE => 'BCarray' ) ), "{$p}<var name='0'><struct><var name='x'><number>1</number></var></struct></var>{$s}" ),
- array( array( array( 'a', 'b', ApiResult::META_TYPE => 'BCassoc' ) ), "{$p}<var name='0'><array length='2'><string>a</string><string>b</string></array></var>{$s}" ),
-
- // Content
- array( array( 'content' => 'foo', ApiResult::META_CONTENT => 'content' ),
- "{$p}<var name='*'><string>foo</string></var>{$s}" ),
-
- // BC Subelements
- array( array( 'foo' => 'foo', ApiResult::META_BC_SUBELEMENTS => array( 'foo' ) ),
- "{$p}<var name='foo'><struct><var name='*'><string>foo</string></var></struct></var>{$s}" ),
- );
- }
-
- /**
- * @dataProvider provideEncoding
- */
- public function testSlowEncoding( array $data, $expect, array $params = array() ) {
- // Adjust expectation for differences between fast and slow printers.
- $expect = str_replace( '\'', '"', $expect );
- $expect = str_replace( '/>', ' />', $expect );
- $expect = '<?xml version="1.0"?>' . $expect;
-
- $this->assertSame( $expect, $this->encodeData( $params, $data, 'ApiFormatWddxTest_SlowWddx' ) );
- }
-}
-
-class ApiFormatWddxTest_SlowWddx extends ApiFormatWddx {
- public static function useSlowPrinter() {
- return true;
- }
-}
diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php
index ce2f70de..db61bc80 100644
--- a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php
+++ b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php
@@ -57,10 +57,9 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase {
} else {
$params['action'] = 'query';
}
- if ( $useContinue && !isset( $params['continue'] ) ) {
+ // Silence warning
+ if ( !isset( $params['continue'] ) ) {
$params['continue'] = '';
- } else {
- $params['rawcontinue'] = '1';
}
$count = 0;
$result = array();
diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php
index 5f061b50..61b992ba 100644
--- a/tests/phpunit/includes/api/query/ApiQueryTest.php
+++ b/tests/phpunit/includes/api/query/ApiQueryTest.php
@@ -131,7 +131,7 @@ class ApiQueryTest extends ApiTestCase {
);
$queryApi = new ApiQuery( $api, 'query' );
$modules = $queryApi->getModuleManager()->getNamesWithClasses();
- foreach( $modules as $name => $class ) {
+ foreach ( $modules as $name => $class ) {
$this->assertArrayHasKey(
$class,
$classes,
diff --git a/tests/phpunit/includes/api/query/ApiQueryTestBase.php b/tests/phpunit/includes/api/query/ApiQueryTestBase.php
index dabf72e0..d5fa4542 100644
--- a/tests/phpunit/includes/api/query/ApiQueryTestBase.php
+++ b/tests/phpunit/includes/api/query/ApiQueryTestBase.php
@@ -56,12 +56,12 @@ STR;
* @return array
*/
private function validateRequestExpectedPair( $v ) {
- $this->assertType( 'array', $v, self::PARAM_ASSERT );
+ $this->assertInternalType( 'array', $v, self::PARAM_ASSERT );
$this->assertEquals( 2, count( $v ), self::PARAM_ASSERT );
$this->assertArrayHasKey( 0, $v, self::PARAM_ASSERT );
$this->assertArrayHasKey( 1, $v, self::PARAM_ASSERT );
- $this->assertType( 'array', $v[0], self::PARAM_ASSERT );
- $this->assertType( 'array', $v[1], self::PARAM_ASSERT );
+ $this->assertInternalType( 'array', $v[0], self::PARAM_ASSERT );
+ $this->assertInternalType( 'array', $v[1], self::PARAM_ASSERT );
return $v;
}
@@ -87,6 +87,7 @@ STR;
/**
* Checks that the request's result matches the expected results.
+ * Assumes no rawcontinue and a complete batch.
* @param array $values Array is a two element array( request, expected_results )
* @param array $session
* @param bool $appendModule
@@ -99,8 +100,9 @@ STR;
if ( !array_key_exists( 'action', $req ) ) {
$req['action'] = 'query';
}
- if ( !array_key_exists( 'continue', $req ) ) {
- $req['rawcontinue'] = '1';
+ // Silence warning
+ if ( !isset( $params['continue'] ) ) {
+ $params['continue'] = '';
}
foreach ( $req as &$val ) {
if ( is_array( $val ) ) {
@@ -108,7 +110,7 @@ STR;
}
}
$result = $this->doApiRequest( $req, $session, $appendModule, $user );
- $this->assertResult( array( 'query' => $exp ), $result[0], $req );
+ $this->assertResult( array( 'batchcomplete' => true, 'query' => $exp ), $result[0], $req );
}
protected function assertResult( $exp, $result, $message = '' ) {
diff --git a/tests/phpunit/includes/cache/MessageCacheTest.php b/tests/phpunit/includes/cache/MessageCacheTest.php
index 442e9f9f..5302b363 100644
--- a/tests/phpunit/includes/cache/MessageCacheTest.php
+++ b/tests/phpunit/includes/cache/MessageCacheTest.php
@@ -52,7 +52,7 @@ class MessageCacheTest extends MediaWikiLangTestCase {
$this->makePage( 'MessageCacheTest-FullKeyTest', 'ru' );
// In content language -- get base if no derivative
- $this->makePage( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none', false );
+ $this->makePage( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none' );
}
/**
@@ -61,15 +61,14 @@ class MessageCacheTest extends MediaWikiLangTestCase {
* @param string $title Title of page to be created
* @param string $lang Language and content of the created page
* @param string|null $content Content of the created page, or null for a generic string
- * @param bool $createSubPage Set to false if a root page should be created
*/
- protected function makePage( $title, $lang, $content = null, $createSubPage = true ) {
+ protected function makePage( $title, $lang, $content = null ) {
global $wgContLang;
if ( $content === null ) {
$content = $lang;
}
- if ( $lang !== $wgContLang->getCode() || $createSubPage ) {
+ if ( $lang !== $wgContLang->getCode() ) {
$title = "$title/$lang";
}
@@ -125,4 +124,26 @@ class MessageCacheTest extends MediaWikiLangTestCase {
);
}
+ /**
+ * @dataProvider provideNormalizeKey
+ */
+ public function testNormalizeKey( $key, $expected ) {
+ $actual = MessageCache::normalizeKey( $key );
+ $this->assertEquals( $expected, $actual );
+ }
+
+ public function provideNormalizeKey() {
+ return array(
+ array( 'Foo', 'foo' ),
+ array( 'foo', 'foo' ),
+ array( 'fOo', 'fOo' ),
+ array( 'FOO', 'fOO' ),
+ array( 'Foo bar', 'foo_bar' ),
+ array( 'Ćab', 'ćab' ),
+ array( 'Ćab_e 3', 'ćab_e_3' ),
+ array( 'ĆAB', 'ćAB' ),
+ array( 'ćab', 'ćab' ),
+ array( 'ćaB', 'ćaB' ),
+ );
+ }
}
diff --git a/tests/phpunit/includes/changes/RecentChangeTest.php b/tests/phpunit/includes/changes/RecentChangeTest.php
index b3cb7b52..4d1a936e 100644
--- a/tests/phpunit/includes/changes/RecentChangeTest.php
+++ b/tests/phpunit/includes/changes/RecentChangeTest.php
@@ -10,8 +10,8 @@ class RecentChangeTest extends MediaWikiTestCase {
protected $user_comment;
protected $context;
- public function __construct() {
- parent::__construct();
+ public function setUp() {
+ parent::setUp();
$this->title = Title::newFromText( 'SomeTitle' );
$this->target = Title::newFromText( 'TestTarget' );
@@ -22,6 +22,26 @@ class RecentChangeTest extends MediaWikiTestCase {
}
/**
+ * @covers RecentChange::newFromRow
+ * @covers RecentChange::loadFromRow
+ */
+ public function testNewFromRow() {
+ $row = new stdClass();
+ $row->rc_foo = 'AAA';
+ $row->rc_timestamp = '20150921134808';
+ $row->rc_deleted = 'bar';
+
+ $rc = RecentChange::newFromRow( $row );
+
+ $expected = array(
+ 'rc_foo' => 'AAA',
+ 'rc_timestamp' => '20150921134808',
+ 'rc_deleted' => 'bar',
+ );
+ $this->assertEquals( $expected, $rc->getAttributes() );
+ }
+
+ /**
* The testIrcMsgForAction* tests are supposed to cover the hacky
* LogFormatter::getIRCActionText / bug 34508
*
@@ -46,6 +66,7 @@ class RecentChangeTest extends MediaWikiTestCase {
* - protect/protect
* - protect/modifyprotect
* - protect/unprotect
+ * - protect/move_prot
* - upload/upload
* - merge/merge
* - import/upload
@@ -59,289 +80,95 @@ class RecentChangeTest extends MediaWikiTestCase {
*/
/**
- * @covers LogFormatter::getIRCActionText
- */
- public function testIrcMsgForLogTypeBlock() {
- $sep = $this->context->msg( 'colon-separator' )->text();
-
- # block/block
- $this->assertIRCComment(
- $this->context->msg( 'blocklogentry', 'SomeTitle', 'duration', '(flags)' )->plain()
- . $sep . $this->user_comment,
- 'block', 'block',
- array(
- '5::duration' => 'duration',
- '6::flags' => 'flags',
- ),
- $this->user_comment
- );
- # block/unblock
- $this->assertIRCComment(
- $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'block', 'unblock',
- array(),
- $this->user_comment
- );
- # block/reblock
- $this->assertIRCComment(
- $this->context->msg( 'reblock-logentry', 'SomeTitle', 'duration', '(flags)' )->plain()
- . $sep . $this->user_comment,
- 'block', 'reblock',
- array(
- '5::duration' => 'duration',
- '6::flags' => 'flags',
- ),
- $this->user_comment
- );
- }
-
- /**
- * @covers LogFormatter::getIRCActionText
- */
- public function testIrcMsgForLogTypeDelete() {
- $sep = $this->context->msg( 'colon-separator' )->text();
-
- # delete/delete
- $this->assertIRCComment(
- $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'delete', 'delete',
- array(),
- $this->user_comment
- );
-
- # delete/restore
- $this->assertIRCComment(
- $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'delete', 'restore',
- array(),
- $this->user_comment
- );
- }
-
- /**
- * @covers LogFormatter::getIRCActionText
- */
- public function testIrcMsgForLogTypeNewusers() {
- $this->assertIRCComment(
- 'New user account',
- 'newusers', 'newusers',
- array()
- );
- $this->assertIRCComment(
- 'New user account',
- 'newusers', 'create',
- array()
- );
- $this->assertIRCComment(
- 'created new account SomeTitle',
- 'newusers', 'create2',
- array()
- );
- $this->assertIRCComment(
- 'Account created automatically',
- 'newusers', 'autocreate',
- array()
- );
- }
-
- /**
- * @covers LogFormatter::getIRCActionText
- */
- public function testIrcMsgForLogTypeMove() {
- $move_params = array(
- '4::target' => $this->target->getPrefixedText(),
- '5::noredir' => 0,
- );
- $sep = $this->context->msg( 'colon-separator' )->text();
-
- # move/move
- $this->assertIRCComment(
- $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )
- ->plain() . $sep . $this->user_comment,
- 'move', 'move',
- $move_params,
- $this->user_comment
- );
-
- # move/move_redir
- $this->assertIRCComment(
- $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )
- ->plain() . $sep . $this->user_comment,
- 'move', 'move_redir',
- $move_params,
- $this->user_comment
- );
- }
-
- /**
- * @covers LogFormatter::getIRCActionText
+ * @covers RecentChange::parseParams
*/
- public function testIrcMsgForLogTypePatrol() {
- # patrol/patrol
- $this->assertIRCComment(
- $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(),
- 'patrol', 'patrol',
- array(
- '4::curid' => '777',
- '5::previd' => '666',
- '6::auto' => 0,
+ public function testParseParams() {
+ $params = array(
+ 'root' => array(
+ 'A' => 1,
+ 'B' => 'two'
)
);
- }
- /**
- * @covers LogFormatter::getIRCActionText
- */
- public function testIrcMsgForLogTypeProtect() {
- $protectParams = array(
- '[edit=sysop] (indefinite) ‎[move=sysop] (indefinite)'
+ $this->assertParseParams(
+ $params,
+ 'a:1:{s:4:"root";a:2:{s:1:"A";i:1;s:1:"B";s:3:"two";}}'
);
- $sep = $this->context->msg( 'colon-separator' )->text();
- # protect/protect
- $this->assertIRCComment(
- $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )
- ->plain() . $sep . $this->user_comment,
- 'protect', 'protect',
- $protectParams,
- $this->user_comment
+ $this->assertParseParams(
+ null,
+ null
);
- # protect/unprotect
- $this->assertIRCComment(
- $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'protect', 'unprotect',
- array(),
- $this->user_comment
+ $this->assertParseParams(
+ null,
+ serialize( false )
);
- # protect/modify
- $this->assertIRCComment(
- $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )
- ->plain() . $sep . $this->user_comment,
- 'protect', 'modify',
- $protectParams,
- $this->user_comment
+ $this->assertParseParams(
+ null,
+ 'not-an-array'
);
}
/**
- * @covers LogFormatter::getIRCActionText
+ * @param array $expectedParseParams
+ * @param string|null $rawRcParams
*/
- public function testIrcMsgForLogTypeUpload() {
- $sep = $this->context->msg( 'colon-separator' )->text();
+ protected function assertParseParams( $expectedParseParams, $rawRcParams ) {
+ $rc = new RecentChange;
+ $rc->setAttribs( array( 'rc_params' => $rawRcParams ) );
- # upload/upload
- $this->assertIRCComment(
- $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'upload', 'upload',
- array(),
- $this->user_comment
- );
+ $actualParseParams = $rc->parseParams();
- # upload/overwrite
- $this->assertIRCComment(
- $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'upload', 'overwrite',
- array(),
- $this->user_comment
- );
+ $this->assertEquals( $expectedParseParams, $actualParseParams );
}
/**
- * @covers LogFormatter::getIRCActionText
+ * 50 mins and 100 mins are used here as the tests never take that long!
+ * @return array
*/
- public function testIrcMsgForLogTypeMerge() {
- $sep = $this->context->msg( 'colon-separator' )->text();
-
- # merge/merge
- $this->assertIRCComment(
- $this->context->msg( 'pagemerge-logentry', 'SomeTitle', 'Dest', 'timestamp' )->plain()
- . $sep . $this->user_comment,
- 'merge', 'merge',
- array(
- '4::dest' => 'Dest',
- '5::mergepoint' => 'timestamp',
- ),
- $this->user_comment
+ public function provideIsInRCLifespan() {
+ return array(
+ array( 6000, time() - 3000, 0, true ),
+ array( 3000, time() - 6000, 0, false ),
+ array( 6000, time() - 3000, 6000, true ),
+ array( 3000, time() - 6000, 6000, true ),
);
}
/**
- * @covers LogFormatter::getIRCActionText
+ * @covers RecentChange::isInRCLifespan
+ * @dataProvider provideIsInRCLifespan
*/
- public function testIrcMsgForLogTypeImport() {
- $sep = $this->context->msg( 'colon-separator' )->text();
-
- # import/upload
- $this->assertIRCComment(
- $this->context->msg( 'import-logentry-upload', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'import', 'upload',
- array(),
- $this->user_comment
- );
+ public function testIsInRCLifespan( $maxAge, $timestamp, $tolerance, $expected ) {
+ $this->setMwGlobals( 'wgRCMaxAge', $maxAge );
+ $this->assertEquals( $expected, RecentChange::isInRCLifespan( $timestamp, $tolerance ) );
+ }
- # import/interwiki
- $this->assertIRCComment(
- $this->context->msg( 'import-logentry-interwiki', 'SomeTitle' )->plain() . $sep . $this->user_comment,
- 'import', 'interwiki',
- array(),
- $this->user_comment
+ public function provideRCTypes() {
+ return array(
+ array( RC_EDIT, 'edit' ),
+ array( RC_NEW, 'new' ),
+ array( RC_LOG, 'log' ),
+ array( RC_EXTERNAL, 'external' ),
);
}
/**
- * @todo Emulate these edits somehow and extract
- * raw edit summary from RecentChange object
- * --
+ * @dataProvider provideRCTypes
+ * @covers RecentChange::parseFromRCType
*/
- /*
- public function testIrcMsgForBlankingAES() {
- // $this->context->msg( 'autosumm-blank', .. );
- }
-
- public function testIrcMsgForReplaceAES() {
- // $this->context->msg( 'autosumm-replace', .. );
- }
-
- public function testIrcMsgForRollbackAES() {
- // $this->context->msg( 'revertpage', .. );
+ public function testParseFromRCType( $rcType, $type ) {
+ $this->assertEquals( $type, RecentChange::parseFromRCType( $rcType ) );
}
- public function testIrcMsgForUndoAES() {
- // $this->context->msg( 'undo-summary', .. );
- }
- */
-
/**
- * @param string $expected Expected IRC text without colors codes
- * @param string $type Log type (move, delete, suppress, patrol ...)
- * @param string $action A log type action
- * @param array $params
- * @param string $comment (optional) A comment for the log action
- * @param string $msg (optional) A message for PHPUnit :-)
+ * @dataProvider provideRCTypes
+ * @covers RecentChange::parseToRCType
*/
- protected function assertIRCComment( $expected, $type, $action, $params,
- $comment = null, $msg = ''
- ) {
- $logEntry = new ManualLogEntry( $type, $action );
- $logEntry->setPerformer( $this->user );
- $logEntry->setTarget( $this->title );
- if ( $comment !== null ) {
- $logEntry->setComment( $comment );
- }
- $logEntry->setParameters( $params );
-
- $formatter = LogFormatter::newFromEntry( $logEntry );
- $formatter->setContext( $this->context );
-
- // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment
- $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() );
-
- $this->assertEquals(
- $expected,
- $ircRcComment,
- $msg
- );
+ public function testParseToRCType( $rcType, $type ) {
+ $this->assertEquals( $rcType, RecentChange::parseToRCType( $type ) );
}
+
}
diff --git a/tests/phpunit/includes/config/HashConfigTest.php b/tests/phpunit/includes/config/HashConfigTest.php
index 06973b09..4aa3e30c 100644
--- a/tests/phpunit/includes/config/HashConfigTest.php
+++ b/tests/phpunit/includes/config/HashConfigTest.php
@@ -30,7 +30,7 @@ class HashConfigTest extends MediaWikiTestCase {
public function testGet() {
$conf = new HashConfig( array(
'one' => '1',
- ));
+ ) );
$this->assertEquals( '1', $conf->get( 'one' ) );
$this->setExpectedException( 'ConfigException', 'HashConfig::get: undefined option' );
$conf->get( 'two' );
diff --git a/tests/phpunit/includes/content/ContentHandlerTest.php b/tests/phpunit/includes/content/ContentHandlerTest.php
index 988a59ee..8178c12e 100644
--- a/tests/phpunit/includes/content/ContentHandlerTest.php
+++ b/tests/phpunit/includes/content/ContentHandlerTest.php
@@ -22,6 +22,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
'wgContentHandlers' => array(
CONTENT_MODEL_WIKITEXT => 'WikitextContentHandler',
CONTENT_MODEL_JAVASCRIPT => 'JavaScriptContentHandler',
+ CONTENT_MODEL_JSON => 'JsonContentHandler',
CONTENT_MODEL_CSS => 'CssContentHandler',
CONTENT_MODEL_TEXT => 'TextContentHandler',
'testing' => 'DummyContentHandlerForTesting',
@@ -51,19 +52,27 @@ class ContentHandlerTest extends MediaWikiTestCase {
return array(
array( 'Help:Foo', CONTENT_MODEL_WIKITEXT ),
array( 'Help:Foo.js', CONTENT_MODEL_WIKITEXT ),
+ array( 'Help:Foo.css', CONTENT_MODEL_WIKITEXT ),
+ array( 'Help:Foo.json', CONTENT_MODEL_WIKITEXT ),
array( 'Help:Foo/bar.js', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo.js', CONTENT_MODEL_WIKITEXT ),
+ array( 'User:Foo.css', CONTENT_MODEL_WIKITEXT ),
+ array( 'User:Foo.json', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ),
array( 'User:Foo/bar.css', CONTENT_MODEL_CSS ),
+ array( 'User:Foo/bar.json', CONTENT_MODEL_JSON ),
+ array( 'User:Foo/bar.json.nope', CONTENT_MODEL_WIKITEXT ),
array( 'User talk:Foo/bar.css', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo/bar.js.xxx', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo/bar.xxx', CONTENT_MODEL_WIKITEXT ),
array( 'MediaWiki:Foo.js', CONTENT_MODEL_JAVASCRIPT ),
- array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ),
array( 'MediaWiki:Foo.JS', CONTENT_MODEL_WIKITEXT ),
- array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ),
+ array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ),
array( 'MediaWiki:Foo.css.xxx', CONTENT_MODEL_WIKITEXT ),
+ array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ),
+ array( 'MediaWiki:Foo.json', CONTENT_MODEL_JSON ),
+ array( 'MediaWiki:Foo.JSON', CONTENT_MODEL_WIKITEXT ),
);
}
@@ -338,6 +347,11 @@ class ContentHandlerTest extends MediaWikiTestCase {
}
*/
+ public function testSupportsDirectEditing() {
+ $handler = new DummyContentHandlerForTesting( CONTENT_MODEL_JSON );
+ $this->assertFalse( $handler->supportsDirectEditing(), 'direct editing is not supported' );
+ }
+
/**
* @covers ContentHandler::runLegacyHooks
*/
@@ -365,164 +379,3 @@ class ContentHandlerTest extends MediaWikiTestCase {
return true;
}
}
-
-class DummyContentHandlerForTesting extends ContentHandler {
-
- public function __construct( $dataModel ) {
- parent::__construct( $dataModel, array( "testing" ) );
- }
-
- /**
- * @see ContentHandler::serializeContent
- *
- * @param Content $content
- * @param string $format
- *
- * @return string
- */
- public function serializeContent( Content $content, $format = null ) {
- return $content->serialize();
- }
-
- /**
- * @see ContentHandler::unserializeContent
- *
- * @param string $blob
- * @param string $format Unused.
- *
- * @return Content
- */
- public function unserializeContent( $blob, $format = null ) {
- $d = unserialize( $blob );
-
- return new DummyContentForTesting( $d );
- }
-
- /**
- * Creates an empty Content object of the type supported by this ContentHandler.
- *
- */
- public function makeEmptyContent() {
- return new DummyContentForTesting( '' );
- }
-}
-
-class DummyContentForTesting extends AbstractContent {
-
- public function __construct( $data ) {
- parent::__construct( "testing" );
-
- $this->data = $data;
- }
-
- public function serialize( $format = null ) {
- return serialize( $this->data );
- }
-
- /**
- * @return string A string representing the content in a way useful for
- * building a full text search index. If no useful representation exists,
- * this method returns an empty string.
- */
- public function getTextForSearchIndex() {
- return '';
- }
-
- /**
- * @return string|bool The wikitext to include when another page includes this content,
- * or false if the content is not includable in a wikitext page.
- */
- public function getWikitextForTransclusion() {
- return false;
- }
-
- /**
- * Returns a textual representation of the content suitable for use in edit
- * summaries and log messages.
- *
- * @param int $maxlength Maximum length of the summary text.
- * @return string The summary text.
- */
- public function getTextForSummary( $maxlength = 250 ) {
- return '';
- }
-
- /**
- * Returns native represenation of the data. Interpretation depends on the data model used,
- * as given by getDataModel().
- *
- * @return mixed The native representation of the content. Could be a string, a nested array
- * structure, an object, a binary blob... anything, really.
- */
- public function getNativeData() {
- return $this->data;
- }
-
- /**
- * returns the content's nominal size in bogo-bytes.
- *
- * @return int
- */
- public function getSize() {
- return strlen( $this->data );
- }
-
- /**
- * Return a copy of this Content object. The following must be true for the object returned
- * if $copy = $original->copy()
- *
- * * get_class($original) === get_class($copy)
- * * $original->getModel() === $copy->getModel()
- * * $original->equals( $copy )
- *
- * If and only if the Content object is imutable, the copy() method can and should
- * return $this. That is, $copy === $original may be true, but only for imutable content
- * objects.
- *
- * @return Content A copy of this object
- */
- public function copy() {
- return $this;
- }
-
- /**
- * Returns true if this content is countable as a "real" wiki page, provided
- * that it's also in a countable location (e.g. a current revision in the main namespace).
- *
- * @param bool $hasLinks If it is known whether this content contains links,
- * provide this information here, to avoid redundant parsing to find out.
- * @return bool
- */
- public function isCountable( $hasLinks = null ) {
- return false;
- }
-
- /**
- * @param Title $title
- * @param int $revId Unused.
- * @param null|ParserOptions $options
- * @param bool $generateHtml Whether to generate Html (default: true). If false, the result
- * of calling getText() on the ParserOutput object returned by this method is undefined.
- *
- * @return ParserOutput
- */
- public function getParserOutput( Title $title, $revId = null,
- ParserOptions $options = null, $generateHtml = true
- ) {
- return new ParserOutput( $this->getNativeData() );
- }
-
- /**
- * @see AbstractContent::fillParserOutput()
- *
- * @param Title $title Context title for parsing
- * @param int|null $revId Revision ID (for {{REVISIONID}})
- * @param ParserOptions $options Parser options
- * @param bool $generateHtml Whether or not to generate HTML
- * @param ParserOutput &$output The output object to fill (reference).
- */
- protected function fillParserOutput( Title $title, $revId,
- ParserOptions $options, $generateHtml, ParserOutput &$output ) {
- $output = new ParserOutput( $this->getNativeData() );
- }
-}
diff --git a/tests/phpunit/includes/content/CssContentHandlerTest.php b/tests/phpunit/includes/content/CssContentHandlerTest.php
new file mode 100644
index 00000000..e1785a96
--- /dev/null
+++ b/tests/phpunit/includes/content/CssContentHandlerTest.php
@@ -0,0 +1,30 @@
+<?php
+
+class CssContentHandlerTest extends MediaWikiTestCase {
+
+ /**
+ * @dataProvider provideMakeRedirectContent
+ * @covers CssContentHandler::makeRedirectContent
+ */
+ public function testMakeRedirectContent( $title, $expected ) {
+ $this->setMwGlobals( array(
+ 'wgServer' => '//example.org',
+ 'wgScript' => '/w/index.php',
+ ) );
+ $ch = new CssContentHandler();
+ $content = $ch->makeRedirectContent( Title::newFromText( $title ) );
+ $this->assertInstanceOf( 'CssContent', $content );
+ $this->assertEquals( $expected, $content->serialize( CONTENT_FORMAT_CSS ) );
+ }
+
+ /**
+ * Keep this in sync with CssContentTest::provideGetRedirectTarget()
+ */
+ public static function provideMakeRedirectContent() {
+ return array(
+ array( 'MediaWiki:MonoBook.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=MediaWiki:MonoBook.css&action=raw&ctype=text/css);" ),
+ array( 'User:FooBar/common.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=User:FooBar/common.css&action=raw&ctype=text/css);" ),
+ array( 'Gadget:FooBaz.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ),
+ );
+ }
+}
diff --git a/tests/phpunit/includes/content/CssContentTest.php b/tests/phpunit/includes/content/CssContentTest.php
index 40484d3a..c4d87c24 100644
--- a/tests/phpunit/includes/content/CssContentTest.php
+++ b/tests/phpunit/includes/content/CssContentTest.php
@@ -4,6 +4,8 @@
* @group ContentHandler
* @group Database
* ^--- needed, because we do need the database to test link updates
+ *
+ * @FIXME this should not extend JavaScriptContentTest.
*/
class CssContentTest extends JavaScriptContentTest {
@@ -68,7 +70,48 @@ class CssContentTest extends JavaScriptContentTest {
$this->assertEquals( CONTENT_MODEL_CSS, $content->getContentHandler()->getModelID() );
}
- public static function dataEquals() {
+ /**
+ * Redirects aren't supported
+ */
+ public static function provideUpdateRedirect() {
+ return array(
+ array(
+ '#REDIRECT [[Someplace]]',
+ '#REDIRECT [[Someplace]]',
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideGetRedirectTarget
+ */
+ public function testGetRedirectTarget( $title, $text ) {
+ $this->setMwGlobals( array(
+ 'wgServer' => '//example.org',
+ 'wgScriptPath' => '/w',
+ 'wgScript' => '/w/index.php',
+ ) );
+ $content = new CssContent( $text );
+ $target = $content->getRedirectTarget();
+ $this->assertEquals( $title, $target ? $target->getPrefixedText() : null );
+ }
+
+ /**
+ * Keep this in sync with CssContentHandlerTest::provideMakeRedirectContent()
+ */
+ public static function provideGetRedirectTarget() {
+ return array(
+ array( 'MediaWiki:MonoBook.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=MediaWiki:MonoBook.css&action=raw&ctype=text/css);" ),
+ array( 'User:FooBar/common.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=User:FooBar/common.css&action=raw&ctype=text/css);" ),
+ array( 'Gadget:FooBaz.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ),
+ # No #REDIRECT comment
+ array( null, "@import url(//example.org/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ),
+ # Wrong domain
+ array( null, "/* #REDIRECT */@import url(//example.com/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ),
+ );
+ }
+
+ public static function dataEquals() {
return array(
array( new CssContent( 'hallo' ), null, false ),
array( new CssContent( 'hallo' ), new CssContent( 'hallo' ), true ),
diff --git a/tests/phpunit/includes/content/JavaScriptContentHandlerTest.php b/tests/phpunit/includes/content/JavaScriptContentHandlerTest.php
new file mode 100644
index 00000000..0f41020f
--- /dev/null
+++ b/tests/phpunit/includes/content/JavaScriptContentHandlerTest.php
@@ -0,0 +1,30 @@
+<?php
+
+class JavaScriptContentHandlerTest extends MediaWikiTestCase {
+
+ /**
+ * @dataProvider provideMakeRedirectContent
+ * @covers JavaScriptContentHandler::makeRedirectContent
+ */
+ public function testMakeRedirectContent( $title, $expected ) {
+ $this->setMwGlobals( array(
+ 'wgServer' => '//example.org',
+ 'wgScript' => '/w/index.php',
+ ) );
+ $ch = new JavaScriptContentHandler();
+ $content = $ch->makeRedirectContent( Title::newFromText( $title ) );
+ $this->assertInstanceOf( 'JavaScriptContent', $content );
+ $this->assertEquals( $expected, $content->serialize( CONTENT_FORMAT_JAVASCRIPT ) );
+ }
+
+ /**
+ * Keep this in sync with JavaScriptContentTest::provideGetRedirectTarget()
+ */
+ public static function provideMakeRedirectContent() {
+ return array(
+ array( 'MediaWiki:MonoBook.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=MediaWiki:MonoBook.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ array( 'User:FooBar/common.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=User:FooBar/common.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ array( 'Gadget:FooBaz.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=Gadget:FooBaz.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ );
+ }
+}
diff --git a/tests/phpunit/includes/content/JavaScriptContentTest.php b/tests/phpunit/includes/content/JavaScriptContentTest.php
index 7193ec9f..0ee27129 100644
--- a/tests/phpunit/includes/content/JavaScriptContentTest.php
+++ b/tests/phpunit/includes/content/JavaScriptContentTest.php
@@ -251,16 +251,31 @@ class JavaScriptContentTest extends TextContentTest {
/**
* @covers JavaScriptContent::updateRedirect
+ * @dataProvider provideUpdateRedirect
*/
- public function testUpdateRedirect() {
+ public function testUpdateRedirect( $oldText, $expectedText) {
+ $this->setMwGlobals( array(
+ 'wgServer' => '//example.org',
+ 'wgScriptPath' => '/w/index.php',
+ ) );
$target = Title::newFromText( "testUpdateRedirect_target" );
- $content = $this->newContent( "#REDIRECT [[Someplace]]" );
+ $content = new JavaScriptContent( $oldText );
$newContent = $content->updateRedirect( $target );
- $this->assertTrue(
- $content->equals( $newContent ),
- "content should be unchanged since it's not wikitext"
+ $this->assertEquals( $expectedText, $newContent->getNativeData() );
+ }
+
+ public static function provideUpdateRedirect() {
+ return array(
+ array(
+ '#REDIRECT [[Someplace]]',
+ '#REDIRECT [[Someplace]]',
+ ),
+ array(
+ '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=MediaWiki:MonoBook.js\u0026action=raw\u0026ctype=text/javascript");',
+ '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=TestUpdateRedirect_target\u0026action=raw\u0026ctype=text/javascript");'
+ )
);
}
@@ -290,4 +305,32 @@ class JavaScriptContentTest extends TextContentTest {
array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "HALLO" ), false ),
);
}
+
+ /**
+ * @dataProvider provideGetRedirectTarget
+ */
+ public function testGetRedirectTarget( $title, $text ) {
+ $this->setMwGlobals( array(
+ 'wgServer' => '//example.org',
+ 'wgScriptPath' => '/w/index.php',
+ ) );
+ $content = new JavaScriptContent( $text );
+ $target = $content->getRedirectTarget();
+ $this->assertEquals( $title, $target ? $target->getPrefixedText() : null );
+ }
+
+ /**
+ * Keep this in sync with JavaScriptContentHandlerTest::provideMakeRedirectContent()
+ */
+ public static function provideGetRedirectTarget() {
+ return array(
+ array( 'MediaWiki:MonoBook.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=MediaWiki:MonoBook.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ array( 'User:FooBar/common.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=User:FooBar/common.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ array( 'Gadget:FooBaz.js', '/* #REDIRECT */mw.loader.load("//example.org/w/index.php?title=Gadget:FooBaz.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ // No #REDIRECT comment
+ array( null, 'mw.loader.load("//example.org/w/index.php?title=MediaWiki:NoRedirect.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ // Different domain
+ array( null, '/* #REDIRECT */mw.loader.load("//example.com/w/index.php?title=MediaWiki:OtherWiki.js\u0026action=raw\u0026ctype=text/javascript");' ),
+ );
+ }
}
diff --git a/tests/phpunit/includes/content/JsonContentTest.php b/tests/phpunit/includes/content/JsonContentTest.php
index cccfe7b1..8a9d2ab0 100644
--- a/tests/phpunit/includes/content/JsonContentTest.php
+++ b/tests/phpunit/includes/content/JsonContentTest.php
@@ -138,7 +138,7 @@ class JsonContentTest extends MediaWikiLangTestCase {
'<tr><th>0</th><td class="value">"bar"</td></tr></tbody></table>'
),
array(
- (object)array( '<script>alert("evil!")</script>'),
+ (object)array( '<script>alert("evil!")</script>' ),
'<table class="mw-json"><tbody><tr><th>0</th><td class="value">"' .
'&lt;script>alert("evil!")&lt;/script>"' .
'</td></tr></tbody></table>',
diff --git a/tests/phpunit/includes/content/TextContentHandlerTest.php b/tests/phpunit/includes/content/TextContentHandlerTest.php
new file mode 100644
index 00000000..492fec6b
--- /dev/null
+++ b/tests/phpunit/includes/content/TextContentHandlerTest.php
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * @group ContentHandler
+ */
+class TextContentHandlerTest extends MediaWikiLangTestCase {
+ public function testSupportsDirectEditing() {
+ $handler = new TextContentHandler();
+ $this->assertTrue( $handler->supportsDirectEditing(), 'direct editing is supported' );
+ }
+
+}
diff --git a/tests/phpunit/includes/content/TextContentTest.php b/tests/phpunit/includes/content/TextContentTest.php
index dd61f85b..fe263756 100644
--- a/tests/phpunit/includes/content/TextContentTest.php
+++ b/tests/phpunit/includes/content/TextContentTest.php
@@ -27,10 +27,16 @@ class TextContentTest extends MediaWikiLangTestCase {
CONTENT_MODEL_JAVASCRIPT,
),
'wgUseTidy' => false,
- 'wgAlwaysUseTidy' => false,
'wgCapitalLinks' => true,
'wgHooks' => array(), // bypass hook ContentGetParserOutput that force custom rendering
) );
+
+ MWTidy::destroySingleton();
+ }
+
+ protected function tearDown() {
+ MWTidy::destroySingleton();
+ parent::tearDown();
}
public function newContent( $text ) {
diff --git a/tests/phpunit/includes/content/WikitextContentHandlerTest.php b/tests/phpunit/includes/content/WikitextContentHandlerTest.php
index 38fb5733..361238b7 100644
--- a/tests/phpunit/includes/content/WikitextContentHandlerTest.php
+++ b/tests/phpunit/includes/content/WikitextContentHandlerTest.php
@@ -115,6 +115,11 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
$this->assertEquals( $supported, $this->handler->isSupportedFormat( $format ) );
}
+ public function testSupportsDirectEditing() {
+ $handler = new WikiTextContentHandler();
+ $this->assertTrue( $handler->supportsDirectEditing(), 'direct editing is supported' );
+ }
+
public static function dataMerge3() {
return array(
array(
diff --git a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
index b4292a60..42ea58e5 100644
--- a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
+++ b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
@@ -181,7 +181,7 @@ class DatabaseMysqlBaseTest extends MediaWikiTestCase {
array( 'Tables_in_' => 'view2' ),
array( 'Tables_in_' => 'myview' ),
false # no more rows
- ));
+ ) );
return $db;
}
/**
diff --git a/tests/phpunit/includes/db/DatabaseSqliteTest.php b/tests/phpunit/includes/db/DatabaseSqliteTest.php
index 645baf1f..3db9172a 100644
--- a/tests/phpunit/includes/db/DatabaseSqliteTest.php
+++ b/tests/phpunit/includes/db/DatabaseSqliteTest.php
@@ -1,12 +1,13 @@
<?php
-class MockDatabaseSqlite extends DatabaseSqlite {
+class DatabaseSqliteMock extends DatabaseSqlite {
private $lastQuery;
public static function newInstance( array $p = array() ) {
$p['dbFilePath'] = ':memory:';
+ $p['schema'] = false;
- return new self( $p );
+ return DatabaseBase::factory( 'SqliteMock', $p );
}
function query( $sql, $fname = '', $tempIgnore = false ) {
@@ -29,7 +30,7 @@ class MockDatabaseSqlite extends DatabaseSqlite {
* @group medium
*/
class DatabaseSqliteTest extends MediaWikiTestCase {
- /** @var MockDatabaseSqlite */
+ /** @var DatabaseSqliteMock */
protected $db;
protected function setUp() {
@@ -38,7 +39,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
if ( !Sqlite::isPresent() ) {
$this->markTestSkipped( 'No SQLite support detected' );
}
- $this->db = MockDatabaseSqlite::newInstance();
+ $this->db = DatabaseSqliteMock::newInstance();
if ( version_compare( $this->db->getServerVersion(), '3.6.0', '<' ) ) {
$this->markTestSkipped( "SQLite at least 3.6 required, {$this->db->getServerVersion()} found" );
}
@@ -188,18 +189,34 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
public function testDuplicateTableStructure() {
$db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
$db->query( 'CREATE TABLE foo(foo, barfoo)' );
+ $db->query( 'CREATE INDEX index1 ON foo(foo)' );
+ $db->query( 'CREATE UNIQUE INDEX index2 ON foo(barfoo)' );
$db->duplicateTableStructure( 'foo', 'bar' );
$this->assertEquals( 'CREATE TABLE "bar"(foo, barfoo)',
$db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ),
'Normal table duplication'
);
+ $indexList = $db->query( 'PRAGMA INDEX_LIST("bar")' );
+ $index = $indexList->next();
+ $this->assertEquals( 'bar_index1', $index->name );
+ $this->assertEquals( '0', $index->unique );
+ $index = $indexList->next();
+ $this->assertEquals( 'bar_index2', $index->name );
+ $this->assertEquals( '1', $index->unique );
$db->duplicateTableStructure( 'foo', 'baz', true );
$this->assertEquals( 'CREATE TABLE "baz"(foo, barfoo)',
$db->selectField( 'sqlite_temp_master', 'sql', array( 'name' => 'baz' ) ),
'Creation of temporary duplicate'
);
+ $indexList = $db->query( 'PRAGMA INDEX_LIST("baz")' );
+ $index = $indexList->next();
+ $this->assertEquals( 'baz_index1', $index->name );
+ $this->assertEquals( '0', $index->unique );
+ $index = $indexList->next();
+ $this->assertEquals( 'baz_index2', $index->name );
+ $this->assertEquals( '1', $index->unique );
$this->assertEquals( 0,
$db->selectField( 'sqlite_master', 'COUNT(*)', array( 'name' => 'baz' ) ),
'Create a temporary duplicate only'
diff --git a/tests/phpunit/includes/db/ORMTableTest.php b/tests/phpunit/includes/db/ORMTableTest.php
index 338d931f..764560d5 100644
--- a/tests/phpunit/includes/db/ORMTableTest.php
+++ b/tests/phpunit/includes/db/ORMTableTest.php
@@ -68,25 +68,6 @@ class ORMTableTest extends MediaWikiTestCase {
$this->assertInstanceOf( $class, $class::singleton() );
$this->assertTrue( $class::singleton() === $class::singleton() );
}
-
- /**
- * @since 1.21
- */
- public function testIgnoreErrorsOverride() {
- $table = $this->getTable();
-
- $db = $table->getReadDbConnection();
- $db->ignoreErrors( true );
-
- try {
- $table->rawSelect( "this is invalid" );
- $this->fail( "An invalid query should trigger a DBQueryError even if ignoreErrors is enabled." );
- } catch ( DBQueryError $ex ) {
- $this->assertTrue( true, "just making phpunit happy" );
- }
-
- $db->ignoreErrors( false );
- }
}
/**
diff --git a/tests/phpunit/includes/debug/MWDebugTest.php b/tests/phpunit/includes/debug/MWDebugTest.php
index 1abb47e7..7280a97b 100644
--- a/tests/phpunit/includes/debug/MWDebugTest.php
+++ b/tests/phpunit/includes/debug/MWDebugTest.php
@@ -12,11 +12,11 @@ class MWDebugTest extends MediaWikiTestCase {
}
/** Clear log before each test */
MWDebug::clearLog();
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
}
protected function tearDown() {
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
parent::tearDown();
}
diff --git a/tests/phpunit/includes/debug/logging/LegacyLoggerTest.php b/tests/phpunit/includes/debug/logger/LegacyLoggerTest.php
index 415fa045..1b3ce2ca 100644
--- a/tests/phpunit/includes/debug/logging/LegacyLoggerTest.php
+++ b/tests/phpunit/includes/debug/logger/LegacyLoggerTest.php
@@ -35,6 +35,8 @@ class LegacyLoggerTest extends MediaWikiTestCase {
}
public function provideInterpolate() {
+ $e = new \Exception( 'boom!' );
+ $d = new \DateTime();
return array(
array(
'no-op',
@@ -68,6 +70,57 @@ class LegacyLoggerTest extends MediaWikiTestCase {
),
'{ not interpolated }',
),
+ array(
+ '{null}',
+ array(
+ 'null' => null,
+ ),
+ '[Null]',
+ ),
+ array(
+ '{bool}',
+ array(
+ 'bool' => true,
+ ),
+ 'true',
+ ),
+ array(
+ '{float}',
+ array(
+ 'float' => 1.23,
+ ),
+ '1.23',
+ ),
+ array(
+ '{array}',
+ array(
+ 'array' => array( 1, 2, 3 ),
+ ),
+ '[Array(3)]',
+ ),
+ array(
+ '{exception}',
+ array(
+ 'exception' => $e,
+ ),
+ '[Exception ' . get_class( $e ) . '( ' .
+ $e->getFile() . ':' . $e->getLine() . ') ' .
+ $e->getMessage() . ']',
+ ),
+ array(
+ '{datetime}',
+ array(
+ 'datetime' => $d,
+ ),
+ $d->format( 'c' ),
+ ),
+ array(
+ '{object}',
+ array(
+ 'object' => new \stdClass,
+ ),
+ '[Object stdClass]',
+ ),
);
}
diff --git a/tests/phpunit/includes/debug/logger/MonologSpiTest.php b/tests/phpunit/includes/debug/logger/MonologSpiTest.php
new file mode 100644
index 00000000..aa0a54ff
--- /dev/null
+++ b/tests/phpunit/includes/debug/logger/MonologSpiTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MediaWiki\Logger;
+
+use MediaWikiTestCase;
+use TestingAccessWrapper;
+
+class MonologSpiTest extends MediaWikiTestCase {
+
+ /**
+ * @covers MonologSpi::mergeConfig
+ */
+ public function testMergeConfig() {
+ $base = array(
+ 'loggers' => array(
+ '@default' => array(
+ 'processors' => array( 'constructor' ),
+ 'handlers' => array( 'constructor' ),
+ ),
+ ),
+ 'processors' => array(
+ 'constructor' => array(
+ 'class' => 'constructor',
+ ),
+ ),
+ 'handlers' => array(
+ 'constructor' => array(
+ 'class' => 'constructor',
+ 'formatter' => 'constructor',
+ ),
+ ),
+ 'formatters' => array(
+ 'constructor' => array(
+ 'class' => 'constructor',
+ ),
+ ),
+ );
+
+ $fixture = new MonologSpi( $base );
+ $this->assertSame(
+ $base,
+ TestingAccessWrapper::newFromObject( $fixture )->config
+ );
+
+ $fixture->mergeConfig( array(
+ 'loggers' => array(
+ 'merged' => array(
+ 'processors' => array( 'merged' ),
+ 'handlers' => array( 'merged' ),
+ ),
+ ),
+ 'processors' => array(
+ 'merged' => array(
+ 'class' => 'merged',
+ ),
+ ),
+ 'magic' => array(
+ 'idkfa' => array( 'xyzzy' ),
+ ),
+ 'handlers' => array(
+ 'merged' => array(
+ 'class' => 'merged',
+ 'formatter' => 'merged',
+ ),
+ ),
+ 'formatters' => array(
+ 'merged' => array(
+ 'class' => 'merged',
+ ),
+ ),
+ ) );
+ $this->assertSame(
+ array(
+ 'loggers' => array(
+ '@default' => array(
+ 'processors' => array( 'constructor' ),
+ 'handlers' => array( 'constructor' ),
+ ),
+ 'merged' => array(
+ 'processors' => array( 'merged' ),
+ 'handlers' => array( 'merged' ),
+ ),
+ ),
+ 'processors' => array(
+ 'constructor' => array(
+ 'class' => 'constructor',
+ ),
+ 'merged' => array(
+ 'class' => 'merged',
+ ),
+ ),
+ 'handlers' => array(
+ 'constructor' => array(
+ 'class' => 'constructor',
+ 'formatter' => 'constructor',
+ ),
+ 'merged' => array(
+ 'class' => 'merged',
+ 'formatter' => 'merged',
+ ),
+ ),
+ 'formatters' => array(
+ 'constructor' => array(
+ 'class' => 'constructor',
+ ),
+ 'merged' => array(
+ 'class' => 'merged',
+ ),
+ ),
+ 'magic' => array(
+ 'idkfa' => array( 'xyzzy' ),
+ ),
+ ),
+ TestingAccessWrapper::newFromObject( $fixture )->config
+ );
+ }
+
+}
diff --git a/tests/phpunit/includes/debug/logger/monolog/AvroFormatterTest.php b/tests/phpunit/includes/debug/logger/monolog/AvroFormatterTest.php
new file mode 100644
index 00000000..44242ed2
--- /dev/null
+++ b/tests/phpunit/includes/debug/logger/monolog/AvroFormatterTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * This program is fr