mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/TemplateData
synced 2024-11-27 17:20:01 +00:00
Implement new 'autovalue' parameter property
Add an 'autovalue' parameter property to the TemplateData spec. And implement it in the validation for the API and in the editor. Also added tests to make sure all parameter attributes preserve their values before and after parsing, including the 'autovalue' parameter. Bug: 51428 Change-Id: Iffb376a804d39388d2b5b6ea3583ef2a292eea41
This commit is contained in:
parent
949401fa10
commit
4f3e647758
|
@ -95,6 +95,7 @@ $wgResourceModules['ext.templateDataGenerator.core'] = array(
|
|||
'templatedata-modal-notice-import-numparams',
|
||||
'templatedata-modal-table-param-actions',
|
||||
'templatedata-modal-table-param-aliases',
|
||||
'templatedata-modal-table-param-autovalue',
|
||||
'templatedata-modal-table-param-default',
|
||||
'templatedata-modal-table-param-desc',
|
||||
'templatedata-modal-table-param-label',
|
||||
|
|
|
@ -88,6 +88,7 @@ class TemplateDataBlob {
|
|||
'description',
|
||||
'deprecated',
|
||||
'aliases',
|
||||
'autovalue',
|
||||
'default',
|
||||
'inherits',
|
||||
'type',
|
||||
|
@ -254,6 +255,20 @@ class TemplateDataBlob {
|
|||
$paramObj->aliases = array();
|
||||
}
|
||||
|
||||
// Param.autovalue
|
||||
if ( isset( $paramObj->autovalue ) ) {
|
||||
if ( !is_string( $paramObj->autovalue ) ) {
|
||||
// TODO: Validate the autovalue values.
|
||||
return Status::newFatal(
|
||||
'templatedata-invalid-type',
|
||||
"params.{$paramName}.autovalue",
|
||||
'string'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$paramObj->autovalue = null;
|
||||
}
|
||||
|
||||
// Param.default
|
||||
if ( isset( $paramObj->default ) ) {
|
||||
if ( !is_string( $paramObj->default ) ) {
|
||||
|
@ -586,6 +601,11 @@ class TemplateDataBlob {
|
|||
array(),
|
||||
wfMessage( 'templatedata-doc-param-default' )->inLanguage( $lang )->text()
|
||||
)
|
||||
. Html::element(
|
||||
'th',
|
||||
array(),
|
||||
wfMessage( 'templatedata-doc-param-autovalue' )->inLanguage( $lang )->text()
|
||||
)
|
||||
. Html::element(
|
||||
'th',
|
||||
array(),
|
||||
|
@ -659,6 +679,16 @@ class TemplateDataBlob {
|
|||
$paramObj->default :
|
||||
wfMessage( 'templatedata-doc-param-default-empty' )->inLanguage( $lang )->text()
|
||||
)
|
||||
// Auto value
|
||||
. Html::rawElement( 'td', array(
|
||||
'class' => array(
|
||||
'mw-templatedata-doc-muted' => $paramObj->autovalue === null
|
||||
)
|
||||
),
|
||||
$paramObj->autovalue !== null ?
|
||||
Html::element( 'code', array(), $paramObj->autovalue ) :
|
||||
wfMessage( 'templatedata-doc-param-autovalue-empty' )->inLanguage( $lang )->escaped()
|
||||
)
|
||||
// Status
|
||||
. Html::element( 'td', array(), wfMessage( $status )->inLanguage( $lang )->text() )
|
||||
. '</tr>';
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
},
|
||||
"templatedata-desc": "Implement data storage for template parameters (using JSON)",
|
||||
"templatedata-doc-desc-empty": "No description.",
|
||||
"templatedata-doc-param-autovalue": "Auto value",
|
||||
"templatedata-doc-param-autovalue-empty": "empty",
|
||||
"templatedata-doc-param-default": "Default",
|
||||
"templatedata-doc-param-default-empty": "empty",
|
||||
"templatedata-doc-param-desc": "Description",
|
||||
|
@ -41,6 +43,7 @@
|
|||
"templatedata-modal-notice-import-numparams": "$1 new {{PLURAL:$1|parameter was|parameters were}} imported.",
|
||||
"templatedata-modal-table-param-actions": "Actions",
|
||||
"templatedata-modal-table-param-aliases": "Aliases (comma separated)",
|
||||
"templatedata-modal-table-param-autovalue": "Auto value",
|
||||
"templatedata-modal-table-param-default": "Default",
|
||||
"templatedata-modal-table-param-desc": "Description",
|
||||
"templatedata-modal-table-param-label": "Label",
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
},
|
||||
"templatedata-desc": "{{desc|name=Template Data|url=http://www.mediawiki.org/wiki/Extension:TemplateData}}",
|
||||
"templatedata-doc-desc-empty": "Displayed when a template has no description (should be a valid sentence).\n{{Identical|No description}}",
|
||||
"templatedata-doc-param-autovalue": "Used as column heading in the table for auto fill value.\n{{Related|Templatedata-doc-param}}\n",
|
||||
"templatedata-doc-param-autovalue-empty": "Displayed when a template parameter has no auto filled value (should not be a full sentence, used in a table).\n{{Identical|Empty}}",
|
||||
"templatedata-doc-param-default": "Used as column heading in the table.\n{{Related|Templatedata-doc-param}}\n{{Identical|Default}}",
|
||||
"templatedata-doc-param-default-empty": "Displayed when a template parameter has no default value (should not be a full sentence, used in a table).\n{{Identical|Empty}}",
|
||||
"templatedata-doc-param-desc": "Used as column heading in the table.\n{{Related|Templatedata-doc-param}}\n{{Identical|Description}}",
|
||||
|
@ -47,6 +49,7 @@
|
|||
"templatedata-modal-notice-import-numparams": "Message that appears in the TemplateData generator GUI showing how many new parameters were imported into the GUI from an existing template.\n\nParameters:\n* $1 - number of parameters",
|
||||
"templatedata-modal-table-param-actions": "Label for a table heading: Parameter actions in the table",
|
||||
"templatedata-modal-table-param-aliases": "Label for a table heading: Aliases of the parameter, instruct the user to separate aliases with commas.",
|
||||
"templatedata-modal-table-param-autovalue": "Label for a table heading: Parameter auto value in the table",
|
||||
"templatedata-modal-table-param-default": "Label for a table heading: Default value of the parameter.\n{{Identical|Default}}",
|
||||
"templatedata-modal-table-param-desc": "Label for a table heading: Description of the parameter.\n{{Identical|Description}}",
|
||||
"templatedata-modal-table-param-label": "Label for a table heading: Label of the parameter.\n\nSee https://en.wikipedia.org/w/index.php?title=Template:Infobox_treaty/TemplateData&action=edit for example.\n{{Identical|Label}}",
|
||||
|
|
|
@ -1262,6 +1262,12 @@
|
|||
label: 'templatedata-modal-table-param-default',
|
||||
$element: $( '<input>' )
|
||||
},
|
||||
autovalue: {
|
||||
selector: 'input',
|
||||
type: 'wikitext',
|
||||
label: 'templatedata-modal-table-param-autovalue',
|
||||
$element: $( '<input>' )
|
||||
},
|
||||
required: {
|
||||
selector: 'input[type="checkbox"]',
|
||||
type: 'checkbox',
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
@property {string} [inherits] Key to another object in `Root.params`.
|
||||
The current Param object will inherit from that one, with local properties
|
||||
overriding the inherited ones.
|
||||
@property {Type} [autovalue] A dynamically generated default value such as today's
|
||||
date or the editing user's name. Should generally involve substitution,
|
||||
such as {{subst:CURRENTMONTHNAME}}.
|
||||
|
||||
@structure {Object} Set
|
||||
@property {InterfaceText} label Label of this set.
|
||||
|
@ -130,7 +133,8 @@
|
|||
"description": {
|
||||
"en": "Timestamp of when the comment was posted, in YYYY-MM-DD format."
|
||||
},
|
||||
"aliases": ["2"]
|
||||
"aliases": ["2"],
|
||||
"autovalue": '{{subst:#time:Y-m-d}}'
|
||||
},
|
||||
"year": {
|
||||
"label": "Year",
|
||||
|
|
|
@ -95,7 +95,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"suggested": false,
|
||||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["foo"],
|
||||
|
@ -120,6 +121,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"label": null,
|
||||
"description": null,
|
||||
"default": "",
|
||||
"autovalue": null,
|
||||
"required": false,
|
||||
"suggested": false,
|
||||
"deprecated": false,
|
||||
|
@ -167,7 +169,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"aliases": [
|
||||
"1"
|
||||
],
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["nickname"],
|
||||
|
@ -207,7 +210,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"default": "example",
|
||||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
},
|
||||
"2d": {
|
||||
"label": null,
|
||||
|
@ -219,7 +223,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"default": "overridden",
|
||||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["1d", "2d"],
|
||||
|
@ -303,7 +308,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
},
|
||||
"bar": {
|
||||
"label": null,
|
||||
|
@ -313,7 +319,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
},
|
||||
"quux": {
|
||||
"label": null,
|
||||
|
@ -323,7 +330,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["foo", "bar", "quux"],
|
||||
|
@ -344,6 +352,51 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
}',
|
||||
'status' => true
|
||||
),
|
||||
array(
|
||||
'input' => '{
|
||||
"description": "Testing some template description.",
|
||||
"params": {
|
||||
"bar": {
|
||||
"label": "Bar label",
|
||||
"description": "Bar description",
|
||||
"default": "Baz",
|
||||
"autovalue": "{{SomeTemplate}}",
|
||||
"required": true,
|
||||
"suggested": false,
|
||||
"deprecated": false,
|
||||
"aliases": [ "foo", "baz" ],
|
||||
"type": "line"
|
||||
}
|
||||
}
|
||||
}
|
||||
',
|
||||
'output' => '{
|
||||
"description": {
|
||||
"en": "Testing some template description."
|
||||
},
|
||||
"params": {
|
||||
"bar": {
|
||||
"label": {
|
||||
"en": "Bar label"
|
||||
},
|
||||
"description": {
|
||||
"en": "Bar description"
|
||||
},
|
||||
"default": "Baz",
|
||||
"autovalue": "{{SomeTemplate}}",
|
||||
"required": true,
|
||||
"suggested": false,
|
||||
"deprecated": false,
|
||||
"aliases": [ "foo", "baz" ],
|
||||
"type": "line"
|
||||
}
|
||||
},
|
||||
"paramOrder": ["bar"],
|
||||
"sets": []
|
||||
}
|
||||
',
|
||||
'msg' => 'Parameter attributes preserve information.'
|
||||
),
|
||||
array(
|
||||
// Should be long enough to trigger this condition after gzipping.
|
||||
'input' => '{
|
||||
|
@ -370,6 +423,42 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
return $str;
|
||||
}
|
||||
|
||||
private static function ksort( Array &$input ) {
|
||||
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
|
||||
*/
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
protected function assertTemplateData( Array $case ) {
|
||||
// Expand defaults
|
||||
if ( !isset( $case['status'] ) ) {
|
||||
|
@ -402,7 +491,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
'Status: ' . $case['msg']
|
||||
);
|
||||
}
|
||||
$this->assertJsonStringEqualsJsonString(
|
||||
|
||||
$this->assertStrictJsonEquals(
|
||||
$case['output'],
|
||||
$actual,
|
||||
$case['msg']
|
||||
|
@ -421,7 +511,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
$this->assertJsonStringEqualsJsonString(
|
||||
$this->assertStrictJsonEquals(
|
||||
$case['output'],
|
||||
$t->getJSON(),
|
||||
'Roundtrip: ' . $case['msg']
|
||||
|
@ -568,7 +658,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["foo"],
|
||||
|
@ -601,7 +692,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["foo"],
|
||||
|
@ -638,7 +730,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["foo"],
|
||||
|
@ -715,7 +808,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
},
|
||||
"bar": {
|
||||
"label": null,
|
||||
|
@ -725,7 +819,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
},
|
||||
"baz": {
|
||||
"label": null,
|
||||
|
@ -735,7 +830,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["foo", "bar", "baz"],
|
||||
|
@ -765,7 +861,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
},
|
||||
"bar": {
|
||||
"label": null,
|
||||
|
@ -775,7 +872,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
},
|
||||
"baz": {
|
||||
"label": null,
|
||||
|
@ -785,7 +883,8 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
|
|||
"deprecated": false,
|
||||
"aliases": [],
|
||||
"default": "",
|
||||
"type": "unknown"
|
||||
"type": "unknown",
|
||||
"autovalue": null
|
||||
}
|
||||
},
|
||||
"paramOrder": ["baz", "foo", "bar"],
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
' "en": "Timestamp of when the comment was posted, in YYYY-MM-DD format."' +
|
||||
' },' +
|
||||
' "aliases": ["2"],' +
|
||||
' "autovalue": "{{subst:CURRENTMONTHNAME}}",' +
|
||||
' "suggested": true' +
|
||||
' },' +
|
||||
' "year": {' +
|
||||
|
@ -71,6 +72,7 @@
|
|||
' "aliases": [\n' +
|
||||
' "2"\n' +
|
||||
' ],\n' +
|
||||
' "autovalue": "{{subst:CURRENTMONTHNAME}}",\n' +
|
||||
' "suggested": true\n' +
|
||||
' },\n' +
|
||||
' "year": {\n' +
|
||||
|
@ -115,6 +117,7 @@
|
|||
'description': {
|
||||
'en': 'Timestamp of when the comment was posted, in YYYY-MM-DD format.'
|
||||
},
|
||||
'autovalue': '{{subst:CURRENTMONTHNAME}}',
|
||||
'aliases': ['2'],
|
||||
'suggested': true
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue