2013-04-16 14:18:10 +00:00
|
|
|
<?php
|
2014-07-07 22:54:25 +00:00
|
|
|
|
2020-08-19 13:29:55 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
|
|
|
|
2014-07-07 22:54:25 +00:00
|
|
|
/**
|
|
|
|
* @group TemplateData
|
2019-07-08 01:46:33 +00:00
|
|
|
* @group Database
|
2020-10-08 09:11:17 +00:00
|
|
|
* @covers \TemplateDataBlob
|
|
|
|
* @covers \TemplateDataCompressedBlob
|
2014-07-07 22:54:25 +00:00
|
|
|
*/
|
2021-08-28 10:48:23 +00:00
|
|
|
class TemplateDataBlobTest extends MediaWikiIntegrationTestCase {
|
2013-04-16 14:18:10 +00:00
|
|
|
|
2021-07-23 22:51:45 +00:00
|
|
|
protected function setUp(): void {
|
2013-04-16 14:18:10 +00:00
|
|
|
parent::setUp();
|
2021-08-28 10:48:23 +00:00
|
|
|
$this->setMwGlobals( 'wgLanguageCode', 'qqx' );
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
|
|
|
|
2013-07-23 13:33:45 +00:00
|
|
|
/**
|
|
|
|
* Helper method to generate a string that gzip can't compress.
|
|
|
|
*
|
|
|
|
* Output is consistent when given the same seed.
|
2021-08-28 09:37:48 +00:00
|
|
|
* @param int $minLength
|
2021-01-17 19:17:57 +00:00
|
|
|
* @param string $seed
|
|
|
|
* @return string
|
2013-07-23 13:33:45 +00:00
|
|
|
*/
|
2021-08-28 09:37:48 +00:00
|
|
|
private static function generatePseudorandomString( $minLength, $seed ) {
|
|
|
|
srand( $seed );
|
2013-07-23 13:33:45 +00:00
|
|
|
$string = '';
|
2021-08-28 09:37:48 +00:00
|
|
|
while ( strlen( $string ) < $minLength ) {
|
|
|
|
$string .= str_shuffle( '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' );
|
2013-07-23 13:33:45 +00:00
|
|
|
}
|
|
|
|
return $string;
|
|
|
|
}
|
2013-10-06 16:31:20 +00:00
|
|
|
|
2013-04-16 14:18:10 +00:00
|
|
|
public static function provideParse() {
|
2016-05-10 00:00:14 +00:00
|
|
|
$cases = [
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '[]
|
2013-04-16 14:18:10 +00:00
|
|
|
',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-type: templatedata, object)'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
2013-05-15 22:15:52 +00:00
|
|
|
"params": {},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-05-15 23:05:06 +00:00
|
|
|
}
|
2013-04-16 14:18:10 +00:00
|
|
|
',
|
2013-05-15 23:05:06 +00:00
|
|
|
'status' => true,
|
|
|
|
'msg' => 'Minimal valid blob'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {},
|
2013-04-16 14:18:10 +00:00
|
|
|
"foo": "bar"
|
|
|
|
}
|
|
|
|
',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-unknown: foo)',
|
2013-05-15 23:05:06 +00:00
|
|
|
'msg' => 'Unknown properties'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '{}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-missing: params, object)',
|
2013-05-15 23:05:06 +00:00
|
|
|
'msg' => 'Empty object'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '{
|
|
|
|
"foo": "bar"
|
|
|
|
}
|
2013-04-16 14:18:10 +00:00
|
|
|
',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-unknown: foo)',
|
2013-05-15 23:05:06 +00:00
|
|
|
'msg' => 'Unknown properties invalidate the blob'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '{
|
2013-04-16 14:18:10 +00:00
|
|
|
"params": {
|
|
|
|
"foo": {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
2013-05-15 23:05:06 +00:00
|
|
|
'output' => '{
|
2013-05-08 23:56:57 +00:00
|
|
|
"description": null,
|
2013-04-16 14:18:10 +00:00
|
|
|
"params": {
|
|
|
|
"foo": {
|
2013-05-08 23:56:57 +00:00
|
|
|
"label": null,
|
|
|
|
"description": null,
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-04-16 14:18:10 +00:00
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-04-16 14:18:10 +00:00
|
|
|
"deprecated": false,
|
2013-05-08 23:56:57 +00:00
|
|
|
"aliases": [],
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
2013-05-15 22:15:52 +00:00
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps": {}
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
|
|
|
',
|
2013-05-15 23:05:06 +00:00
|
|
|
'msg' => 'Optional properties are added if missing'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-24 16:39:04 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"comment": {
|
|
|
|
"type": "string/line"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {
|
|
|
|
"comment": {
|
|
|
|
"label": null,
|
|
|
|
"description": null,
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"autovalue": null,
|
2013-10-24 16:39:04 +00:00
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-24 16:39:04 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
|
|
|
"type": "line"
|
|
|
|
}
|
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps": {}
|
2013-10-24 16:39:04 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => 'Old string/* types are mapped to the unprefixed versions'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '{
|
2013-04-16 14:18:10 +00:00
|
|
|
"description": "User badge MediaWiki developers.",
|
|
|
|
"params": {
|
|
|
|
"nickname": {
|
2013-05-08 23:56:57 +00:00
|
|
|
"label": null,
|
2013-04-16 14:18:10 +00:00
|
|
|
"description": "User name of user who owns the badge",
|
|
|
|
"default": "Base page name of the host page",
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-04-16 14:18:10 +00:00
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": true,
|
2013-04-16 14:18:10 +00:00
|
|
|
"aliases": [
|
|
|
|
"1"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
2013-05-15 23:05:06 +00:00
|
|
|
'output' => '{
|
2013-04-16 14:18:10 +00:00
|
|
|
"description": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "User badge MediaWiki developers."
|
2013-04-16 14:18:10 +00:00
|
|
|
},
|
|
|
|
"params": {
|
|
|
|
"nickname": {
|
2013-05-08 23:56:57 +00:00
|
|
|
"label": null,
|
2013-04-16 14:18:10 +00:00
|
|
|
"description": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "User name of user who owns the badge"
|
2013-04-16 14:18:10 +00:00
|
|
|
},
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Base page name of the host page"
|
2015-03-09 21:45:04 +00:00
|
|
|
},
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-04-16 14:18:10 +00:00
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": true,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-04-16 14:18:10 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [
|
|
|
|
"1"
|
2013-05-08 23:56:57 +00:00
|
|
|
],
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
2013-05-15 22:15:52 +00:00
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps": {}
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
|
|
|
',
|
2013-05-15 23:05:06 +00:00
|
|
|
'msg' => 'InterfaceText is expanded to langcode-keyed object, assuming content language'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 23:05:06 +00:00
|
|
|
'input' => '{
|
2013-04-30 22:32:08 +00:00
|
|
|
"description": "Document the documenter.",
|
|
|
|
"params": {
|
|
|
|
"1d": {
|
|
|
|
"description": "Description of the template parameter",
|
|
|
|
"required": true,
|
|
|
|
"default": "example"
|
|
|
|
},
|
|
|
|
"2d": {
|
|
|
|
"inherits": "1d",
|
|
|
|
"default": "overridden"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
2013-05-15 23:05:06 +00:00
|
|
|
'output' => '{
|
2013-04-30 22:32:08 +00:00
|
|
|
"description": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Document the documenter."
|
2013-04-30 22:32:08 +00:00
|
|
|
},
|
|
|
|
"params": {
|
|
|
|
"1d": {
|
2013-05-08 23:56:57 +00:00
|
|
|
"label": null,
|
2013-04-30 22:32:08 +00:00
|
|
|
"description": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Description of the template parameter"
|
2013-04-30 22:32:08 +00:00
|
|
|
},
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-04-30 22:32:08 +00:00
|
|
|
"required": true,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "example"
|
2015-03-09 21:45:04 +00:00
|
|
|
},
|
2013-04-30 22:32:08 +00:00
|
|
|
"deprecated": false,
|
2013-05-08 23:56:57 +00:00
|
|
|
"aliases": [],
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-04-30 22:32:08 +00:00
|
|
|
},
|
|
|
|
"2d": {
|
2013-05-08 23:56:57 +00:00
|
|
|
"label": null,
|
2013-04-30 22:32:08 +00:00
|
|
|
"description": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Description of the template parameter"
|
2013-04-30 22:32:08 +00:00
|
|
|
},
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-04-30 22:32:08 +00:00
|
|
|
"required": true,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "overridden"
|
2015-03-09 21:45:04 +00:00
|
|
|
},
|
2013-04-30 22:32:08 +00:00
|
|
|
"deprecated": false,
|
2013-05-08 23:56:57 +00:00
|
|
|
"aliases": [],
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-04-30 22:32:08 +00:00
|
|
|
}
|
2013-05-15 22:15:52 +00:00
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-04-30 22:32:08 +00:00
|
|
|
}
|
|
|
|
',
|
2013-05-16 15:01:00 +00:00
|
|
|
'msg' => 'The inherits property copies over properties from another parameter '
|
|
|
|
. '(preserving overides)'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 22:15:52 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {},
|
|
|
|
"sets": [
|
|
|
|
{
|
|
|
|
"label": "Example"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-missing: sets.0.params, array)'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 22:15:52 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [
|
|
|
|
{
|
|
|
|
"params": ["foo"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-missing: sets.0.label, string|object)'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 22:15:52 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [
|
|
|
|
{
|
|
|
|
"label": "Foo with Quux",
|
|
|
|
"params": ["foo", "quux"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-value: sets.0.params[1])'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-05-15 22:15:52 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
},
|
|
|
|
"quux": {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [
|
|
|
|
{
|
|
|
|
"label": "Foo with Quux",
|
|
|
|
"params": ["foo", "quux"]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"label": "Bar with Quux",
|
|
|
|
"params": ["bar", "quux"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-05-15 22:15:52 +00:00
|
|
|
"description": null,
|
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-05-15 22:15:52 +00:00
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-05-15 22:15:52 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-05-15 22:15:52 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-05-15 22:15:52 +00:00
|
|
|
},
|
|
|
|
"quux": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-05-15 22:15:52 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-05-15 22:15:52 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-05-15 22:15:52 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [
|
|
|
|
{
|
|
|
|
"label": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Foo with Quux"
|
2013-05-15 22:15:52 +00:00
|
|
|
},
|
|
|
|
"params": ["foo", "quux"]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"label": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Bar with Quux"
|
2013-05-15 22:15:52 +00:00
|
|
|
},
|
|
|
|
"params": ["bar", "quux"]
|
|
|
|
}
|
2014-10-18 15:28:26 +00:00
|
|
|
],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps": {}
|
2013-05-15 22:15:52 +00:00
|
|
|
}',
|
|
|
|
'status' => true
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2014-09-02 15:29:33 +00:00
|
|
|
'input' => '{
|
|
|
|
"description": "Testing some template description.",
|
|
|
|
"params": {
|
|
|
|
"bar": {
|
|
|
|
"label": "Bar label",
|
|
|
|
"description": "Bar description",
|
|
|
|
"default": "Baz",
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": "Foo bar baz",
|
2014-09-02 15:29:33 +00:00
|
|
|
"autovalue": "{{SomeTemplate}}",
|
|
|
|
"required": true,
|
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [ "baz", "boo" ],
|
2014-09-02 15:29:33 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [ "foo", "baz" ],
|
|
|
|
"type": "line"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Testing some template description."
|
2014-09-02 15:29:33 +00:00
|
|
|
},
|
|
|
|
"params": {
|
|
|
|
"bar": {
|
|
|
|
"label": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Bar label"
|
2014-09-02 15:29:33 +00:00
|
|
|
},
|
|
|
|
"description": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Bar description"
|
2014-09-02 15:29:33 +00:00
|
|
|
},
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Baz"
|
2015-03-09 21:45:04 +00:00
|
|
|
},
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": {
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "Foo bar baz"
|
2015-03-04 20:32:38 +00:00
|
|
|
},
|
2014-09-02 15:29:33 +00:00
|
|
|
"autovalue": "{{SomeTemplate}}",
|
|
|
|
"required": true,
|
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [ "baz", "boo" ],
|
2014-09-02 15:29:33 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [ "foo", "baz" ],
|
|
|
|
"type": "line"
|
|
|
|
}
|
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2014-09-02 15:29:33 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => 'Parameter attributes preserve information.'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2014-10-18 15:28:26 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [],
|
|
|
|
"maps": {
|
|
|
|
"application": {
|
|
|
|
"things": [
|
|
|
|
"foo",
|
|
|
|
["bar", "quux"]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-param: quux, maps.application.things)'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2014-10-18 15:28:26 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [],
|
|
|
|
"maps": {
|
|
|
|
"application": {
|
|
|
|
"things": {
|
|
|
|
"appbar": "bar",
|
|
|
|
"appfoo": "foo"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-type: maps.application.things, string|array)'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2014-10-18 15:28:26 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [],
|
|
|
|
"maps": {
|
|
|
|
"application": {
|
|
|
|
"things": [
|
|
|
|
[ true ]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-type: maps.application.things[0][0], string)'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2015-10-02 10:34:57 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {}
|
|
|
|
},
|
|
|
|
"format": "meshuggah format"
|
|
|
|
}',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-format: format)'
|
2016-08-07 01:03:53 +00:00
|
|
|
],
|
|
|
|
[
|
|
|
|
'input' => '{
|
|
|
|
"params": {},
|
|
|
|
"format": "inline"
|
|
|
|
}',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {},
|
|
|
|
"sets": [],
|
|
|
|
"format": "inline",
|
|
|
|
"maps": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => '"inline" is a valid format string',
|
|
|
|
'status' => true
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'input' => '{
|
|
|
|
"params": {},
|
|
|
|
"format": "block"
|
|
|
|
}',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {},
|
|
|
|
"sets": [],
|
|
|
|
"format": "block",
|
|
|
|
"maps": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => '"block" is a valid format string',
|
|
|
|
'status' => true
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'input' => '{
|
|
|
|
"params": {},
|
|
|
|
"format": "{{_ |\n ___ = _}}"
|
|
|
|
}',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {},
|
|
|
|
"sets": [],
|
|
|
|
"format": "{{_ |\n ___ = _}}",
|
|
|
|
"maps": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => 'Custom parameter format string (1)',
|
|
|
|
'status' => true
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'input' => '{
|
|
|
|
"params": {},
|
|
|
|
"format": "{{_|_=_\n}}\n"
|
|
|
|
}',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {},
|
|
|
|
"sets": [],
|
|
|
|
"format": "{{_|_=_\n}}\n",
|
|
|
|
"maps": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => 'Custom parameter format string (2)',
|
|
|
|
'status' => true
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
];
|
2019-07-08 01:46:33 +00:00
|
|
|
|
2016-05-10 00:00:14 +00:00
|
|
|
$calls = [];
|
2013-05-15 23:05:06 +00:00
|
|
|
foreach ( $cases as $case ) {
|
2016-05-10 00:00:14 +00:00
|
|
|
$calls[] = [ $case ];
|
2013-05-15 23:05:06 +00:00
|
|
|
}
|
|
|
|
return $calls;
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 21:05:33 +00:00
|
|
|
protected static function getStatusText( Status $status ) {
|
2018-08-13 16:57:20 +00:00
|
|
|
$str = Parser::stripOuterParagraph( $status->getHtml() );
|
|
|
|
// Unescape char references for things like "[, "]" and "|" for
|
|
|
|
// cleaner test assertions and output
|
|
|
|
$str = Sanitizer::decodeCharReferences( $str );
|
2013-12-10 21:05:33 +00:00
|
|
|
return $str;
|
|
|
|
}
|
|
|
|
|
2016-05-10 00:00:14 +00:00
|
|
|
private static function ksort( array &$input ) {
|
2014-09-02 15:29:33 +00:00
|
|
|
ksort( $input );
|
|
|
|
foreach ( $input as $key => &$value ) {
|
|
|
|
if ( is_array( $value ) ) {
|
|
|
|
self::ksort( $value );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PHPUnit'a assertEquals does weak comparison, use strict instead.
|
|
|
|
*
|
|
|
|
* There is a built-in assertSame, but that only strictly compares
|
|
|
|
* the top level structure, not the invidual array values.
|
|
|
|
*
|
|
|
|
* so "array( 'a' => '' )" still equals "array( 'a' => null )"
|
|
|
|
* because empty string equals null in PHP's weak comparison.
|
|
|
|
*
|
|
|
|
* @param mixed $expected
|
|
|
|
* @param mixed $actual
|
2021-01-17 19:17:57 +00:00
|
|
|
* @param string|null $message
|
2014-09-02 15:29:33 +00:00
|
|
|
*/
|
|
|
|
protected function assertStrictJsonEquals( $expected, $actual, $message = null ) {
|
|
|
|
// Lazy recursive strict comparison: Serialise to JSON and compare that
|
|
|
|
// Sort first to ensure key-order
|
|
|
|
$expected = json_decode( $expected, /* assoc = */ true );
|
|
|
|
$actual = json_decode( $actual, /* assoc = */ true );
|
|
|
|
self::ksort( $expected );
|
|
|
|
self::ksort( $actual );
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
FormatJson::encode( $expected, true ),
|
|
|
|
FormatJson::encode( $actual, true ),
|
|
|
|
$message
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-05-10 00:00:14 +00:00
|
|
|
protected function assertTemplateData( array $case ) {
|
2013-05-15 23:05:06 +00:00
|
|
|
// Expand defaults
|
2013-10-15 19:40:09 +00:00
|
|
|
if ( !isset( $case['status'] ) ) {
|
|
|
|
$case['status'] = true;
|
2013-05-15 23:05:06 +00:00
|
|
|
}
|
2013-10-15 19:40:09 +00:00
|
|
|
if ( !isset( $case['msg'] ) ) {
|
|
|
|
$case['msg'] = is_string( $case['status'] ) ? $case['status'] : 'TemplateData assertion';
|
2013-05-15 23:05:06 +00:00
|
|
|
}
|
2013-10-15 19:40:09 +00:00
|
|
|
if ( !isset( $case['output'] ) ) {
|
|
|
|
if ( is_string( $case['status'] ) ) {
|
2015-03-04 01:40:40 +00:00
|
|
|
$case['output'] = '{
|
|
|
|
"description": null,
|
|
|
|
"params": {},
|
|
|
|
"sets": [],
|
|
|
|
"maps": {},
|
2019-01-02 00:43:01 +00:00
|
|
|
"format": null
|
2015-03-04 01:40:40 +00:00
|
|
|
}';
|
2013-05-15 23:05:06 +00:00
|
|
|
} else {
|
2013-10-15 19:40:09 +00:00
|
|
|
$case['output'] = $case['input'];
|
2013-05-15 23:05:06 +00:00
|
|
|
}
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
|
|
|
|
2019-07-08 01:46:33 +00:00
|
|
|
$t = TemplateDataBlob::newFromJSON( $this->db, $case['input'] );
|
2013-05-15 23:05:06 +00:00
|
|
|
$actual = $t->getJSON();
|
2013-04-16 14:18:10 +00:00
|
|
|
$status = $t->getStatus();
|
2013-05-15 23:05:06 +00:00
|
|
|
if ( !$status->isGood() ) {
|
|
|
|
$this->assertEquals(
|
2013-10-15 19:40:09 +00:00
|
|
|
$case['status'],
|
2013-12-10 21:05:33 +00:00
|
|
|
self::getStatusText( $status ),
|
2013-10-15 19:40:09 +00:00
|
|
|
'Status: ' . $case['msg']
|
2013-05-15 23:05:06 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$this->assertEquals(
|
2013-10-15 19:40:09 +00:00
|
|
|
$case['status'],
|
2013-05-15 23:05:06 +00:00
|
|
|
$status->isGood(),
|
2013-10-15 19:40:09 +00:00
|
|
|
'Status: ' . $case['msg']
|
2013-05-15 23:05:06 +00:00
|
|
|
);
|
|
|
|
}
|
2014-09-02 15:29:33 +00:00
|
|
|
|
|
|
|
$this->assertStrictJsonEquals(
|
2013-10-15 19:40:09 +00:00
|
|
|
$case['output'],
|
2013-05-15 23:05:06 +00:00
|
|
|
$actual,
|
2013-10-15 19:40:09 +00:00
|
|
|
$case['msg']
|
2013-04-16 14:18:10 +00:00
|
|
|
);
|
2013-10-24 16:34:04 +00:00
|
|
|
|
|
|
|
// Assert this case roundtrips properly by running through the output as input.
|
|
|
|
|
2019-07-08 01:46:33 +00:00
|
|
|
$t = TemplateDataBlob::newFromJSON( $this->db, $case['output'] );
|
2013-10-24 16:34:04 +00:00
|
|
|
|
|
|
|
$status = $t->getStatus();
|
|
|
|
if ( !$status->isGood() ) {
|
|
|
|
$this->assertEquals(
|
|
|
|
$case['status'],
|
2013-12-10 21:05:33 +00:00
|
|
|
self::getStatusText( $status ),
|
2013-10-24 16:34:04 +00:00
|
|
|
'Roundtrip status: ' . $case['msg']
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2014-09-02 15:29:33 +00:00
|
|
|
$this->assertStrictJsonEquals(
|
2013-10-24 16:34:04 +00:00
|
|
|
$case['output'],
|
|
|
|
$t->getJSON(),
|
|
|
|
'Roundtrip: ' . $case['msg']
|
|
|
|
);
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|
2013-09-12 04:02:37 +00:00
|
|
|
|
2013-10-15 19:40:09 +00:00
|
|
|
/**
|
|
|
|
* @dataProvider provideParse
|
|
|
|
*/
|
2016-05-10 00:00:14 +00:00
|
|
|
public function testParse( array $case ) {
|
2013-10-15 19:40:09 +00:00
|
|
|
$this->assertTemplateData( $case );
|
|
|
|
}
|
|
|
|
|
2019-07-08 01:46:33 +00:00
|
|
|
/**
|
|
|
|
* MySQL breaks if the input is too large even after compression
|
|
|
|
*/
|
|
|
|
public function testParseLongString() {
|
2021-08-28 09:37:48 +00:00
|
|
|
if ( $this->db->getType() !== 'mysql' ) {
|
2019-07-08 01:46:33 +00:00
|
|
|
$this->markTestSkipped( 'long compressed strings break on MySQL only' );
|
|
|
|
}
|
2021-08-28 09:37:48 +00:00
|
|
|
|
|
|
|
// Should be long enough to trigger this condition after gzipping.
|
|
|
|
$json = '{
|
|
|
|
"description": "' . self::generatePseudorandomString( 100000, 42 ) . '",
|
|
|
|
"params": {}
|
|
|
|
}';
|
|
|
|
$templateData = TemplateDataBlob::newFromJSON( $this->db, $json );
|
|
|
|
|
|
|
|
$this->assertStringStartsWith(
|
2021-08-28 10:48:23 +00:00
|
|
|
'(templatedata-invalid-length: ',
|
2021-08-28 09:37:48 +00:00
|
|
|
self::getStatusText( $templateData->getStatus() )
|
|
|
|
);
|
2019-07-08 01:46:33 +00:00
|
|
|
}
|
|
|
|
|
2020-08-19 13:29:55 +00:00
|
|
|
/**
|
|
|
|
* @dataProvider provideInterfaceTexts
|
|
|
|
*/
|
|
|
|
public function testIsValidInterfaceText( $text, bool $expected ) {
|
|
|
|
/** @var TemplateDataBlob $parser */
|
|
|
|
$parser = TestingAccessWrapper::newFromObject(
|
|
|
|
TemplateDataBlob::newFromJSON( $this->db, '{}' )
|
|
|
|
);
|
|
|
|
$this->assertSame( $expected, $parser->isValidInterfaceText( $text ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function provideInterfaceTexts() {
|
|
|
|
return [
|
|
|
|
// Invalid stuff
|
|
|
|
[ null, false ],
|
|
|
|
[ [], false ],
|
|
|
|
[ [ 'en' => 'example' ], false ],
|
|
|
|
[ (object)[], false ],
|
|
|
|
[ (object)[ null ], false ],
|
|
|
|
[ (object)[ 'en' => null ], false ],
|
|
|
|
|
|
|
|
[ 'example', true ],
|
|
|
|
[ (object)[ 'de' => 'Beispiel', 'en' => 'example' ], true ],
|
|
|
|
|
|
|
|
// Empty strings are allowed
|
|
|
|
[ '', true ],
|
|
|
|
[ (object)[ 'en' => '' ], true ],
|
|
|
|
|
|
|
|
// Language code can not be empty
|
|
|
|
[ (object)[ '' => 'example' ], false ],
|
|
|
|
[ (object)[ ' ' => 'example' ], false ],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2013-09-12 04:02:37 +00:00
|
|
|
/**
|
|
|
|
* Verify we can gzdecode() which came in PHP 5.4.0. Mediawiki needs a
|
|
|
|
* fallback function for it.
|
|
|
|
* If this test fail, we are most probably attempting to use gzdecode()
|
|
|
|
* with PHP before 5.4.
|
|
|
|
*
|
2019-07-08 01:46:33 +00:00
|
|
|
* @see bug T56058
|
|
|
|
*
|
|
|
|
* Some databases will not be able to store compressed data cleanly
|
|
|
|
* but the object will be initialized properly even if compressed
|
|
|
|
* data are provided
|
|
|
|
*
|
|
|
|
* @see bug T203850
|
2013-09-12 04:02:37 +00:00
|
|
|
*/
|
|
|
|
public function testGetJsonForDatabase() {
|
|
|
|
// Compress JSON to trigger the code pass in newFromDatabase that ends
|
|
|
|
// up calling gzdecode().
|
|
|
|
$gzJson = gzencode( '{}' );
|
2019-07-08 01:46:33 +00:00
|
|
|
$templateData = TemplateDataBlob::newFromDatabase( $this->db, $gzJson );
|
2013-09-12 09:41:07 +00:00
|
|
|
$this->assertInstanceOf( 'TemplateDataBlob', $templateData );
|
2013-09-12 04:02:37 +00:00
|
|
|
}
|
2013-10-06 16:31:20 +00:00
|
|
|
|
|
|
|
public static function provideGetDataInLanguage() {
|
2016-05-10 00:00:14 +00:00
|
|
|
$cases = [
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
|
|
|
"description": {
|
|
|
|
"de": "German",
|
|
|
|
"nl": "Dutch",
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "English",
|
2013-10-06 16:31:20 +00:00
|
|
|
"de-formal": "German (formal address)"
|
|
|
|
},
|
|
|
|
"params": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": "German",
|
|
|
|
"params": {},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'de',
|
|
|
|
'msg' => 'Simple description'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
|
|
|
"description": "Hi",
|
|
|
|
"params": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": "Hi",
|
|
|
|
"params": {},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'fr',
|
2021-08-28 10:48:23 +00:00
|
|
|
'msg' => 'Non multi-language value returned as is (expands to { "qqx": value } for' .
|
|
|
|
' content-lang, "fr" falls back to "qqx")'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
|
|
|
"description": {
|
|
|
|
"nl": "Dutch",
|
|
|
|
"de": "German"
|
|
|
|
},
|
|
|
|
"params": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": "Dutch",
|
|
|
|
"params": {},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'fr',
|
|
|
|
'msg' => 'Try content language before giving up on user language and fallbacks'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
|
|
|
"description": {
|
|
|
|
"es": "Spanish",
|
|
|
|
"de": "German"
|
|
|
|
},
|
|
|
|
"params": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'fr',
|
|
|
|
'msg' => 'Description is optional, use null if no suitable fallback'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
|
|
|
"description": {
|
|
|
|
"de": "German",
|
|
|
|
"nl": "Dutch",
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "English"
|
2013-10-06 16:31:20 +00:00
|
|
|
},
|
|
|
|
"params": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": "German",
|
|
|
|
"params": {},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'de-formal',
|
|
|
|
'msg' => '"de-formal" falls back to "de"'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": {
|
|
|
|
"fr": "French",
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "English"
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": "French",
|
|
|
|
"required": false,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-06 16:31:20 +00:00
|
|
|
"description": null,
|
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'fr',
|
|
|
|
'msg' => 'Simple parameter label'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2015-03-09 21:45:04 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"default": {
|
|
|
|
"fr": "French",
|
2021-08-28 10:48:23 +00:00
|
|
|
"qqx": "English"
|
2015-03-09 21:45:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"default": "French",
|
|
|
|
"required": false,
|
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"description": null,
|
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
|
|
|
"label": null,
|
|
|
|
"type": "unknown",
|
2015-03-04 20:32:38 +00:00
|
|
|
"autovalue": null,
|
|
|
|
"example": null
|
2015-03-09 21:45:04 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2015-03-09 21:45:04 +00:00
|
|
|
"maps" : {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'fr',
|
|
|
|
'msg' => 'Simple parameter default value'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": {
|
|
|
|
"es": "Spanish",
|
|
|
|
"de": "German"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-06 16:31:20 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-06 16:31:20 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'fr',
|
|
|
|
'msg' => 'Parameter label is optional, use null if no matching fallback'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-06 16:31:20 +00:00
|
|
|
'input' => '{
|
2013-10-15 19:40:09 +00:00
|
|
|
"params": {
|
|
|
|
"foo": {}
|
|
|
|
},
|
2013-10-06 16:31:20 +00:00
|
|
|
"sets": [
|
|
|
|
{
|
|
|
|
"label": {
|
|
|
|
"es": "Spanish",
|
|
|
|
"de": "German"
|
|
|
|
},
|
2013-10-15 19:40:09 +00:00
|
|
|
"params": ["foo"]
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
2013-10-15 19:40:09 +00:00
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-15 19:40:09 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-15 19:40:09 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-15 19:40:09 +00:00
|
|
|
}
|
|
|
|
},
|
2013-10-06 16:31:20 +00:00
|
|
|
"sets": [
|
|
|
|
{
|
|
|
|
"label": "Spanish",
|
2013-10-15 19:40:09 +00:00
|
|
|
"params": ["foo"]
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
2014-10-18 15:28:26 +00:00
|
|
|
],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps": {}
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'lang' => 'fr',
|
|
|
|
'msg' => 'Set label is not optional, choose first available key as final fallback'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
];
|
|
|
|
$calls = [];
|
2013-10-06 16:31:20 +00:00
|
|
|
foreach ( $cases as $case ) {
|
2016-05-10 00:00:14 +00:00
|
|
|
$calls[] = [ $case ];
|
2013-10-06 16:31:20 +00:00
|
|
|
}
|
|
|
|
return $calls;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider provideGetDataInLanguage
|
|
|
|
*/
|
2016-05-10 00:00:14 +00:00
|
|
|
public function testGetDataInLanguage( array $case ) {
|
2013-10-06 16:31:20 +00:00
|
|
|
// Change content-language to be non-English so we can distinguish between the
|
|
|
|
// last 'en' fallback and the content language in our tests
|
2018-08-02 22:43:51 +00:00
|
|
|
$this->setContentLang( 'nl' );
|
2013-10-06 16:31:20 +00:00
|
|
|
|
|
|
|
if ( !isset( $case['msg'] ) ) {
|
|
|
|
$case['msg'] = is_string( $case['status'] ) ? $case['status'] : 'TemplateData assertion';
|
|
|
|
}
|
|
|
|
|
2019-07-08 01:46:33 +00:00
|
|
|
$t = TemplateDataBlob::newFromJSON( $this->db, $case['input'] );
|
2013-10-06 16:31:20 +00:00
|
|
|
$status = $t->getStatus();
|
|
|
|
|
2013-12-10 21:05:33 +00:00
|
|
|
$this->assertTrue(
|
|
|
|
$status->isGood() ?: self::getStatusText( $status ),
|
|
|
|
'Status is good: ' . $case['msg']
|
|
|
|
);
|
2013-10-06 16:31:20 +00:00
|
|
|
|
|
|
|
$actual = $t->getDataInLanguage( $case['lang'] );
|
|
|
|
$this->assertJsonStringEqualsJsonString(
|
|
|
|
$case['output'],
|
|
|
|
json_encode( $actual ),
|
|
|
|
$case['msg']
|
|
|
|
);
|
|
|
|
}
|
2013-10-09 22:26:22 +00:00
|
|
|
|
|
|
|
public static function provideParamOrder() {
|
2016-05-10 00:00:14 +00:00
|
|
|
$cases = [
|
|
|
|
[
|
2013-10-09 22:26:22 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {},
|
|
|
|
"bar": {},
|
|
|
|
"baz": {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-09 22:26:22 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-09 22:26:22 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-09 22:26:22 +00:00
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-09 22:26:22 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-09 22:26:22 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-09 22:26:22 +00:00
|
|
|
},
|
|
|
|
"baz": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-09 22:26:22 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-09 22:26:22 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-09 22:26:22 +00:00
|
|
|
}
|
|
|
|
},
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-09 22:26:22 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => 'Normalisation adds paramOrder'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-09 22:26:22 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {},
|
|
|
|
"bar": {},
|
|
|
|
"baz": {}
|
|
|
|
},
|
|
|
|
"paramOrder": ["baz", "foo", "bar"]
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {
|
|
|
|
"foo": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-09 22:26:22 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-09 22:26:22 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-09 22:26:22 +00:00
|
|
|
},
|
|
|
|
"bar": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-09 22:26:22 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-09 22:26:22 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-09 22:26:22 +00:00
|
|
|
},
|
|
|
|
"baz": {
|
|
|
|
"label": null,
|
|
|
|
"required": false,
|
2014-04-24 22:21:36 +00:00
|
|
|
"suggested": false,
|
2021-03-10 10:54:52 +00:00
|
|
|
"suggestedvalues": [],
|
2013-10-09 22:26:22 +00:00
|
|
|
"description": null,
|
2015-03-04 20:32:38 +00:00
|
|
|
"example": null,
|
2013-10-09 22:26:22 +00:00
|
|
|
"deprecated": false,
|
|
|
|
"aliases": [],
|
2015-03-09 21:45:04 +00:00
|
|
|
"default": null,
|
2014-09-02 15:29:33 +00:00
|
|
|
"type": "unknown",
|
|
|
|
"autovalue": null
|
2013-10-09 22:26:22 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
"paramOrder": ["baz", "foo", "bar"],
|
2014-10-18 15:28:26 +00:00
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2014-10-18 15:28:26 +00:00
|
|
|
"maps" : {}
|
2013-10-09 22:26:22 +00:00
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => 'Custom paramOrder'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-09 22:26:22 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {},
|
|
|
|
"bar": {},
|
|
|
|
"baz": {}
|
|
|
|
},
|
|
|
|
"paramOrder": ["foo", "bar"]
|
|
|
|
}
|
|
|
|
',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-missing: paramOrder[2])',
|
2013-10-09 22:26:22 +00:00
|
|
|
'msg' => 'Incomplete paramOrder'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2015-03-04 01:40:40 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'output' => '{
|
|
|
|
"description": null,
|
|
|
|
"params": {},
|
|
|
|
"sets": [],
|
2016-03-01 17:10:23 +00:00
|
|
|
"format": null,
|
2015-03-04 01:40:40 +00:00
|
|
|
"maps" : {}
|
|
|
|
}
|
|
|
|
',
|
|
|
|
'msg' => 'Empty parameter object produces empty array paramOrder'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-09 22:26:22 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {},
|
|
|
|
"bar": {},
|
|
|
|
"baz": {}
|
|
|
|
},
|
|
|
|
"paramOrder": ["foo", "bar", "baz", "quux"]
|
|
|
|
}
|
|
|
|
',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-value: paramOrder[3])',
|
2013-10-09 22:26:22 +00:00
|
|
|
'msg' => 'Unknown params in paramOrder'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
[
|
2013-10-09 22:26:22 +00:00
|
|
|
'input' => '{
|
|
|
|
"params": {
|
|
|
|
"foo": {},
|
|
|
|
"bar": {},
|
|
|
|
"baz": {}
|
|
|
|
},
|
|
|
|
"paramOrder": ["foo", "bar", "baz", "bar"]
|
|
|
|
}
|
|
|
|
',
|
2021-08-28 10:48:23 +00:00
|
|
|
'status' => '(templatedata-invalid-duplicate-value: paramOrder[3], paramOrder[1], bar)',
|
2013-10-09 22:26:22 +00:00
|
|
|
'msg' => 'Duplicate params in paramOrder'
|
2016-05-10 00:00:14 +00:00
|
|
|
],
|
|
|
|
];
|
|
|
|
$calls = [];
|
2013-10-09 22:26:22 +00:00
|
|
|
foreach ( $cases as $case ) {
|
2016-05-10 00:00:14 +00:00
|
|
|
$calls[] = [ $case ];
|
2013-10-09 22:26:22 +00:00
|
|
|
}
|
|
|
|
return $calls;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider provideParamOrder
|
|
|
|
*/
|
2016-05-10 00:00:14 +00:00
|
|
|
public function testParamOrder( array $case ) {
|
2013-10-09 22:26:22 +00:00
|
|
|
$this->assertTemplateData( $case );
|
|
|
|
}
|
2018-04-20 02:18:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider provideGetRawParams
|
|
|
|
*/
|
|
|
|
public function testGetRawParams( $inputWikitext, $expectedParams ) {
|
2018-10-23 04:59:11 +00:00
|
|
|
$params = TemplateDataBlob::getRawParams( $inputWikitext );
|
|
|
|
$this->assertArrayEquals( $expectedParams, $params, true, true );
|
2018-04-20 02:18:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function provideGetRawParams() {
|
|
|
|
return [
|
2018-09-12 02:04:45 +00:00
|
|
|
'No params' => [
|
2018-04-20 02:18:03 +00:00
|
|
|
'Lorem ipsum {{tpl}}.',
|
|
|
|
[]
|
|
|
|
],
|
2018-09-12 02:04:45 +00:00
|
|
|
'Two plain params' => [
|
|
|
|
'Lorem {{{name}}} ipsum {{{surname}}}',
|
|
|
|
[ 'name' => [], 'surname' => [] ]
|
2018-04-20 02:18:03 +00:00
|
|
|
],
|
2018-09-12 02:04:45 +00:00
|
|
|
'Param with multiple casing and default value' => [
|
2018-04-20 02:18:03 +00:00
|
|
|
'Lorem {{{name|{{{Name|Default name}}}}}} ipsum',
|
2018-08-27 03:08:49 +00:00
|
|
|
[ 'name' => [] ]
|
2018-04-20 02:18:03 +00:00
|
|
|
],
|
2018-09-12 02:04:45 +00:00
|
|
|
'Param name contains comment' => [
|
2018-04-20 02:18:03 +00:00
|
|
|
'Lorem {{{name<!-- comment -->}}} ipsum',
|
|
|
|
[ 'name' => [] ]
|
|
|
|
],
|
2018-09-12 02:04:45 +00:00
|
|
|
'Letter-case and underscore-space normalization' => [
|
2018-08-27 03:08:49 +00:00
|
|
|
'Lorem {{{First name|{{{first_name}}}}}} ipsum {{{first-Name}}}',
|
|
|
|
[ 'First name' => [] ]
|
|
|
|
],
|
2018-09-12 02:04:45 +00:00
|
|
|
'Dynamic param name' => [
|
|
|
|
'{{{{{#if:{{{nominee|}}}|nominee|candidate}}|}}}',
|
|
|
|
[ 'nominee' => [] ]
|
|
|
|
],
|
|
|
|
'More complicated dynamic param name' => [
|
|
|
|
'{{{party{{#if:{{{party_election||}}}|_election||}}|}}}',
|
|
|
|
[ 'party_election' => [] ]
|
2018-10-23 04:59:11 +00:00
|
|
|
],
|
|
|
|
'Bang in a param name' => [
|
|
|
|
'{{{!}}} {{{foo!}}}',
|
|
|
|
[ '!' => [], 'foo!' => [] ]
|
|
|
|
],
|
|
|
|
'Bang as a magic word in a table construct' => [
|
|
|
|
'{{{!}} class=""',
|
|
|
|
[]
|
|
|
|
],
|
2019-12-09 18:12:11 +00:00
|
|
|
'Params within comments and nowiki tags' => [
|
|
|
|
'Lorem <!-- {{{name}}} --> ipsum <nowiki > {{{middlename}}}' .
|
|
|
|
'</nowiki> {{{surname}}}',
|
|
|
|
[ 'surname' => [] ]
|
|
|
|
],
|
|
|
|
'Param within comments and param name outside with comment' => [
|
|
|
|
'Lorem {{{name<!--comment-->}}} ipsum <!--{{{surname}}}-->',
|
|
|
|
[ 'name' => [] ]
|
|
|
|
],
|
2020-09-22 16:12:52 +00:00
|
|
|
'safesubst: hack with an unnamed parameter' => [
|
|
|
|
'{{ {{{|safesubst:}}}#invoke:…|{{{1}}}|{{{ 1 }}}}}',
|
|
|
|
[ '1' => [] ]
|
|
|
|
],
|
2018-04-20 02:18:03 +00:00
|
|
|
];
|
|
|
|
}
|
2018-12-28 05:00:45 +00:00
|
|
|
|
|
|
|
public static function provideGetHtml() {
|
|
|
|
// phpcs:disable Generic.Files.LineLength.TooLong
|
|
|
|
yield 'No params' => [
|
|
|
|
[ 'params' => [ (object)[] ] ],
|
|
|
|
<<<HTML
|
2021-07-12 09:45:22 +00:00
|
|
|
<section class="mw-templatedata-doc-wrap">
|
|
|
|
<header><p class="mw-templatedata-doc-desc mw-templatedata-doc-muted">(templatedata-doc-desc-empty)</p></header>
|
2020-06-06 14:07:12 +00:00
|
|
|
<table class="wikitable mw-templatedata-doc-params">
|
2018-12-28 05:00:45 +00:00
|
|
|
<caption><p>(templatedata-doc-params)</p></caption>
|
|
|
|
<thead><tr><th colspan="2">(templatedata-doc-param-name)</th><th>(templatedata-doc-param-desc)</th><th>(templatedata-doc-param-type)</th><th>(templatedata-doc-param-status)</th></tr></thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td class="mw-templatedata-doc-muted" colspan="7">(templatedata-doc-no-params-set)</td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2021-07-12 09:45:22 +00:00
|
|
|
</section>
|
2018-12-28 05:00:45 +00:00
|
|
|
HTML
|
|
|
|
];
|
|
|
|
yield 'Basic params' => [
|
|
|
|
[ 'params' => [ 'foo' => (object)[], 'bar' => [ 'required' => true ] ] ],
|
|
|
|
<<<HTML
|
2021-07-12 09:45:22 +00:00
|
|
|
<section class="mw-templatedata-doc-wrap">
|
|
|
|
<header><p class="mw-templatedata-doc-desc mw-templatedata-doc-muted">(templatedata-doc-desc-empty)</p></header>
|
2018-12-28 05:00:45 +00:00
|
|
|
<table class="wikitable mw-templatedata-doc-params sortable">
|
|
|
|
<caption><p>(templatedata-doc-params)</p></caption>
|
|
|
|
<thead><tr><th colspan="2">(templatedata-doc-param-name)</th><th>(templatedata-doc-param-desc)</th><th>(templatedata-doc-param-type)</th><th>(templatedata-doc-param-status)</th></tr></thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
2020-12-23 07:29:05 +00:00
|
|
|
<th>foo</th>
|
2018-12-28 05:00:45 +00:00
|
|
|
<td class="mw-templatedata-doc-param-name"><code>foo</code></td>
|
|
|
|
<td class="mw-templatedata-doc-muted"><p>(templatedata-doc-param-desc-empty)</p><dl></dl></td>
|
|
|
|
<td class="mw-templatedata-doc-param-type mw-templatedata-doc-muted">(templatedata-doc-param-type-unknown)</td>
|
2020-08-20 11:27:43 +00:00
|
|
|
<td class="mw-templatedata-doc-param-status-optional" data-sort-value="0">(templatedata-doc-param-status-optional)</td>
|
2018-12-28 05:00:45 +00:00
|
|
|
</tr>
|
|
|
|
<tr>
|
2020-12-23 07:29:05 +00:00
|
|
|
<th>bar</th>
|
2018-12-28 05:00:45 +00:00
|
|
|
<td class="mw-templatedata-doc-param-name"><code>bar</code></td>
|
|
|
|
<td class="mw-templatedata-doc-muted"><p>(templatedata-doc-param-desc-empty)</p><dl></dl></td>
|
|
|
|
<td class="mw-templatedata-doc-param-type mw-templatedata-doc-muted">(templatedata-doc-param-type-unknown)</td>
|
2020-08-20 11:27:43 +00:00
|
|
|
<td class="mw-templatedata-doc-param-status-required" data-sort-value="2">(templatedata-doc-param-status-required)</td>
|
2018-12-28 05:00:45 +00:00
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2021-07-12 09:45:22 +00:00
|
|
|
</section>
|
2018-12-28 05:00:45 +00:00
|
|
|
HTML
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider provideGetHtml
|
|
|
|
*/
|
|
|
|
public function testGetHtml( array $data, $expected ) {
|
2019-07-08 01:46:33 +00:00
|
|
|
$t = TemplateDataBlob::newFromJSON( $this->db, json_encode( $data ) );
|
2018-12-28 05:00:45 +00:00
|
|
|
$actual = $t->getHtml( Language::factory( 'qqx' ) );
|
|
|
|
$linedActual = preg_replace( '/>\s*</', ">\n<", $actual );
|
|
|
|
|
|
|
|
$linedExpected = preg_replace( '/>\s*</', ">\n<", trim( $expected ) );
|
|
|
|
|
|
|
|
$this->assertEquals( $linedExpected, $linedActual, 'html' );
|
|
|
|
}
|
2013-04-16 14:18:10 +00:00
|
|
|
}
|