Merge "Add unit tests and fix implemention accordingly"

This commit is contained in:
jenkins-bot 2013-04-22 18:09:49 +00:00 committed by Gerrit Code Review
commit c28968940b
4 changed files with 199 additions and 7 deletions

View file

@ -16,6 +16,15 @@ class TemplateDataHooks {
return true; return true;
} }
/**
* Register unit tests
*/
public static function onUnitTestsList( array &$files ) {
$testDir = __DIR__ . '/tests/';
$files = array_merge( $files, glob( "$testDir/*Test.php" ) );
return true;
}
/** /**
* @param Page &$page * @param Page &$page
* @param User &$user * @param User &$user

View file

@ -33,6 +33,7 @@ $wgAutoloadClasses['ApiTemplateData'] = $dir . '/api/ApiTemplateData.php';
// Register hooks // Register hooks
$wgHooks['ParserFirstCallInit'][] = 'TemplateDataHooks::onParserFirstCallInit'; $wgHooks['ParserFirstCallInit'][] = 'TemplateDataHooks::onParserFirstCallInit';
$wgHooks['PageContentSave'][] = 'TemplateDataHooks::onPageContentSave'; $wgHooks['PageContentSave'][] = 'TemplateDataHooks::onPageContentSave';
$wgHooks['UnitTestsList'][] = 'TemplateDataHooks::onUnitTestsList';
// Register APIs // Register APIs
$wgAPIModules['templatedata'] = 'ApiTemplateData'; $wgAPIModules['templatedata'] = 'ApiTemplateData';

View file

@ -30,8 +30,6 @@ class TemplateDataBlob {
$ti = new self( json_decode( $json ) ); $ti = new self( json_decode( $json ) );
$status = $ti->parse(); $status = $ti->parse();
// TODO: Normalise `params.*.description` to a plain object.
if ( !$status->isOK() ) { if ( !$status->isOK() ) {
// Don't save invalid data, clear it. // Don't save invalid data, clear it.
$ti->data = new stdClass(); $ti->data = new stdClass();
@ -72,11 +70,12 @@ class TemplateDataBlob {
} }
if ( isset( $data->description ) ) { if ( isset( $data->description ) ) {
if ( !is_object( $data->params ) ) { if ( !is_object( $data->description ) && !is_string( $data->description ) ) {
return Status::newFatal( 'templatedata-invalid-type', 'params', 'object' ); return Status::newFatal( 'templatedata-invalid-type', 'description', 'string|object' );
} }
$data->description = self::normaliseInterfaceText( $data->description );
} else { } else {
$data->description = ''; $data->description = self::normaliseInterfaceText( '' );
} }
foreach ( $data->params as $paramName => $paramObj ) { foreach ( $data->params as $paramName => $paramObj ) {
@ -111,8 +110,9 @@ class TemplateDataBlob {
// and the values strings. // and the values strings.
return Status::newFatal( 'templatedata-invalid-type', 'params.' . $paramName . '.description', 'string|object' ); return Status::newFatal( 'templatedata-invalid-type', 'params.' . $paramName . '.description', 'string|object' );
} }
$paramObj->description = self::normaliseInterfaceText( $paramObj->description );
} else { } else {
$paramObj->description = ''; $paramObj->description = self::normaliseInterfaceText( '' );
} }
if ( isset( $paramObj->deprecated ) ) { if ( isset( $paramObj->deprecated ) ) {
@ -153,6 +153,20 @@ class TemplateDataBlob {
return Status::newGood(); return Status::newGood();
} }
/**
* Normalise a InterfaceText field in the TemplateData blob.
* @return stdClass|string $text
*/
protected static function normaliseInterfaceText( $text ) {
if ( is_string( $text ) ) {
global $wgContLang;
$ret = array();
$ret[ $wgContLang->getCode() ] = $text;
return (object) $ret;
}
return $text;
}
public function getStatus() { public function getStatus() {
return $this->status; return $this->status;
} }
@ -207,7 +221,7 @@ class TemplateDataBlob {
return $html; return $html;
} }
private function __construct( stdClass $data = null ) { private function __construct( $data = null ) {
$this->data = $data; $this->data = $data;
} }

View file

@ -0,0 +1,168 @@
<?php
class TemplateDataBlobTest extends MediaWikiTestCase {
protected function setUp() {
parent::setUp();
$this->setMwGlobals( array(
'wgLanguageCode' => 'en',
'wgContLang' => Language::factory( 'en' ),
) );
}
public static function provideParse() {
return array(
array(
'
{}
',
'
{}
',
'Empty object'
),
array(
'
{
"foo": "bar"
}
',
'
{}
',
'Unknown properties are stripped'
),
array(
'
{
"params": {
"foo": {}
}
}
',
'
{
"description": {
"en": ""
},
"params": {
"foo": {
"description": {
"en": ""
},
"default": "",
"required": false,
"deprecated": false,
"aliases": [],
"clones": []
}
}
}
',
'Optional properties are added if missing'
),
array(
'
{
"description": "User badge MediaWiki developers.",
"params": {
"nickname": {
"description": "User name of user who owns the badge",
"default": "Base page name of the host page",
"required": false,
"aliases": [
"1"
]
}
}
}
',
'
{
"description": {
"en": "User badge MediaWiki developers."
},
"params": {
"nickname": {
"description": {
"en": "User name of user who owns the badge"
},
"default": "Base page name of the host page",
"required": false,
"deprecated": false,
"aliases": [
"1"
],
"clones": []
}
}
}
',
'InterfaceText is expanded to langcode-keyed object, assuming content language'
)
);
}
/**
* @dataProvider provideParse
*/
public function testParse( $input, $expected, $msg ) {
$t = TemplateDataBlob::newFromJSON( $input );
$actual = $t->getJSON();
$this->assertJsonStringEqualsJsonString(
$expected,
$actual,
$msg
);
}
public static function provideStatus() {
return array(
array(
'
[]
',
false,
'Not an object'
),
array(
'
{
"params": {}
}
',
true,
'Minimal valid blob'
),
array(
'
{
"params": {},
"foo": "bar"
}
',
false,
'Unknown properties'
),
);
}
/**
* @dataProvider provideStatus
*/
public function testStatus( $inputJSON, $isGood, $msg ) {
// Make sure we don't have two errors cancelling each other out
if ( json_decode( $inputJSON ) === null ) {
throw new Exception( 'Test case provided invalid JSON.' );
}
$t = TemplateDataBlob::newFromJSON( $inputJSON );
$status = $t->getStatus();
$this->assertEquals(
$status->isGood(),
$isGood,
$msg
);
}
}