Add DefinitionReader

Separate file handling and property registration
这个提交包含在:
mwjames 2014-04-19 08:56:04 +09:00
父节点 862c6d6252
当前提交 b9c9a86443
共有 17 个文件被更改,包括 188 次插入110 次删除

查看文件

@ -1,2 +1,2 @@
# Test related files
tests/phpunit/malformed.json
tests/phpunit/Fixture/

查看文件

@ -5,6 +5,10 @@ Released on 2014-04-09
- #31 Fixed error when a User page is created with a subpage
- #32 Migrate to JSON i18n
#### 1.1.1
- #33 Added DefinitionReader
### Version 1.0
Released on 2014-02-23.
@ -28,7 +32,7 @@ For details about the rewrite, its discussion, and changes see #10.
- #10 Fixed incorrect `_REVID` assignment
- #10 Added `_PAGEID` for page ID collection
- #10 Fixed incorrect ``_NTREV`` assignment
- #10 Added ``'_EXIFDATA'`` collection (see [definitions](/src/definitions.json)) which are stored as subobject
- #10 Added ``'_EXIFDATA'`` collection (see [definitions](/src/Definition/definitions.json)) which are stored as subobject
- #10 Fixed "wfMsgGetKey" usage
- #10 Fixed initialization value "is not a number" issue
- #10 Added `sespUseAsFixedTables` setting

查看文件

@ -10,7 +10,7 @@ $GLOBALS['sespSpecialProperties'] = array(
```
## Property identifier
Property identifiers (see [`definitions.json`](/src/definitions.json) ) are used to specify which of the properties are enabled. An indentifier is an internal `ID` which is not to be used during user interaction (e.g. handling in `#ask` queries) instead the property label should be used as reference. These labels differ according to the language the wiki was set up. An easy way to identify them is to navigate to special page "Special:Properies" which contains a listing of all available properties inclucding the special properties provided by this extension.
Property identifiers (see [`definitions.json`](/src/Definition/definitions.json) ) are used to specify which of the properties are enabled. An indentifier is an internal `ID` which is not to be used during user interaction (e.g. handling in `#ask` queries) instead the property label should be used as reference. These labels differ according to the language the wiki was set up. An easy way to identify them is to navigate to special page "Special:Properies" which contains a listing of all available properties inclucding the special properties provided by this extension.
- `_EUSER` add all users that edited this page (expensive; use with care)
- `_CUSER` add user that created this page
@ -23,7 +23,7 @@ very up to date. If [`$wgDisableCounters`][$wgDisableCounters] is set to
- `_NTREV` same but for the talk page, i.e. showing how much discussion is going on around this page
- `_SUBP` add properties for subpages
- `_USERREG` add a property to user pages with the users registration date
- `_EXIFDATA` add properties based on image metadata (Exif data), when available and in case it is a `NS_FILE` namespace object data are stored as a [subobject][subobject]. Details on available Exif data can be found [here](/src/definitions.json).
- `_EXIFDATA` add properties based on image metadata (Exif data), when available and in case it is a `NS_FILE` namespace object data are stored as a [subobject][subobject]. Details on available Exif data can be found [here](/src/Definition/definitions.json).
#### Properties with further dependencies
@ -55,7 +55,7 @@ Setting ``$wgSESPExcludeBots`` to "true" causes bot edits via user accounts in u
#### Property definitions
Details about available properties can be found in the [definitions.json](/src/definitions.json). The file also contains information about the visibility (display in the Factbox etc.) of a property, to alter the characterisctics of non-subobject related properties one can set `show` to `true` for each definition.
Details about available properties can be found in the [definitions.json](/src/Definition/definitions.json). The file also contains information about the visibility (display in the Factbox etc.) of a property, to alter the characterisctics of non-subobject related properties one can set `show` to `true` for each definition.
## Privacy

查看文件

@ -30,7 +30,7 @@ if ( defined( 'SESP_VERSION' ) ) {
return 1;
}
define( 'SESP_VERSION', '1.1.0' );
define( 'SESP_VERSION', '1.1.1' );
if ( is_readable( __DIR__ . '/vendor/autoload.php' ) ) {
include_once( __DIR__ . '/vendor/autoload.php' );
@ -71,6 +71,7 @@ $GLOBALS['wgAutoloadClasses']['SESP\BaseAnnotator'] = __DIR__ . '/src
$GLOBALS['wgAutoloadClasses']['SESP\PropertyRegistry'] = __DIR__ . '/src/PropertyRegistry.php';
$GLOBALS['wgAutoloadClasses']['SESP\ExifDataAnnotator'] = __DIR__ . '/src/ExifDataAnnotator.php';
$GLOBALS['wgAutoloadClasses']['SESP\ShortUrlAnnotator'] = __DIR__ . '/src/ShortUrlAnnotator.php';
$GLOBALS['wgAutoloadClasses']['SESP\Definition\DefinitionReader'] = __DIR__ . '/src/Definition/DefinitionReader.php';
/**
* Setup and initialization

查看文件

@ -18,7 +18,7 @@
"homepage": "https://github.com/rotsee"
},
{
"name": "James Hong Kong",
"name": "mwjames",
"homepage": "https://semantic-mediawiki.org/wiki/User:MWJames"
}
],

查看文件

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="tests/bootstrap.php"
@ -13,7 +14,7 @@
strict="true"
verbose="true">
<testsuites>
<testsuite name="SemanticExtraSpecialProperties">
<testsuite name="semantic-extra-special-properties">
<directory>tests/phpunit</directory>
</testsuite>
</testsuites>

查看文件

@ -0,0 +1,76 @@
<?php
namespace SESP\Definition;
use RuntimeException;
use UnexpectedValueException;
/**
* @ingroup SESP
*
* @licence GNU GPL v2+
* @since 1.1.1
*
* @author mwjames
*/
class DefinitionReader {
protected $definitionFile = null;
protected $definitions = null;
/**
* @since 1.1.1
*
* @param string|null $definitionFile
*/
public function __construct( $definitionFile = null ) {
$this->definitionFile = $definitionFile;
}
/**
* @since 1.1.1
*
* @return array
* @throws RuntimeException
* @throws UnexpectedValueException
*/
public function getDefinitions() {
if ( $this->definitionFile === null ) {
$this->definitionFile = $this->getDefaultDefinitionFile();
}
if ( $this->definitions === null ) {
$this->definitions = $this->acquireDefinitionsFromJsonFile( $this->definitionFile );
}
return $this->definitions;
}
protected function getDefaultDefinitionFile() {
return __DIR__ . '/' . 'definitions.json';
}
protected function acquireDefinitionsFromJsonFile( $definitionFile ) {
$definitionFile = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $definitionFile );
if ( is_readable( $definitionFile ) ) {
return $this->decodeJsonFile( $definitionFile );
}
throw new RuntimeException( "Expected a {$definitionFile} file" );
}
protected function decodeJsonFile( $file ) {
$definitions = json_decode( file_get_contents( $file ), true );
if ( $definitions !== null && is_array( $definitions ) && json_last_error() === JSON_ERROR_NONE ) {
return $definitions;
}
throw new UnexpectedValueException( 'Expected a JSON compatible format' );
}
}

查看文件

@ -2,13 +2,11 @@
namespace SESP;
use SESP\Definition\DefinitionReader;
use SMW\DataTypeRegistry;
use SMW\DIProperty;
use SMWDataItem as DataItem;
use RuntimeException;
use UnexpectedValueException;
/**
* @ingroup SESP
*
@ -24,6 +22,15 @@ class PropertyRegistry {
protected $definitions = null;
/**
* @since 1.1.1
*
* @param DefinitionReader $definitionReader
*/
protected function __construct( DefinitionReader $definitionReader ) {
$this->definitions = $definitionReader->getDefinitions();
}
/**
* @since 1.0
*
@ -32,11 +39,7 @@ class PropertyRegistry {
public static function getInstance() {
if ( self::$instance === null ) {
$instance = new self();
$instance->definitions = $instance->acquireDefinitionsFromJsonFile( $instance->getJsonFile() );
self::$instance = $instance;
self::$instance = new self( new DefinitionReader );
}
return self::$instance;
@ -49,37 +52,6 @@ class PropertyRegistry {
self::$instance = null;
}
/**
* @since 1.0
*/
public function getJsonFile() {
return __DIR__ . '/' . 'definitions.json';
}
/**
* @since 1.0
*
* @param string $path
*
* @return array
* @throws RuntimeException
* @throws UnexpectedValueException
*/
public function acquireDefinitionsFromJsonFile( $path ) {
if ( !is_readable( $path ) ) {
throw new RuntimeException( "Expected a {$path} file" );
}
$definitions = json_decode( file_get_contents( $path ), true );
if ( $definitions !== null && is_array( $definitions ) && json_last_error() === JSON_ERROR_NONE ) {
return $definitions;
}
throw new UnexpectedValueException( 'Expected a JSON compatible format' );
}
/**
* @since 1.0
*
@ -128,13 +100,13 @@ class PropertyRegistry {
$dataItemType = $this->getPropertyType( $externalId );
if ( !isset( $enabledSpecialProperties[$externalId] ) || $dataItemType === null ) {
if ( !isset( $enabledSpecialProperties[ $externalId ] ) || $dataItemType === null ) {
continue;
}
$tableName = 'smw_ftp_sesp' . strtolower( $externalId );
$propertyTableDefinitions[$tableName] = new \SMW\SQLStore\TableDefinition(
$propertyTableDefinitions[ $tableName ] = new \SMW\SQLStore\TableDefinition(
$dataItemType,
$tableName,
$this->getPropertyId( $externalId )

查看文件

@ -4,11 +4,33 @@ if ( php_sapi_name() !== 'cli' ) {
die( 'Not an entry point' );
}
$pwd = getcwd();
chdir( __DIR__ . '/..' );
passthru( 'composer update' );
chdir( $pwd );
if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) {
die( 'You need to install this package with Composer before you can run the tests' );
if ( !defined( 'MEDIAWIKI' ) ) {
die( 'MediaWiki is not available for the test environment' );
}
function registerAutoloaderPath( $identifier, $path ) {
print( "\nUsing the {$identifier} vendor autoloader ...\n" );
return require $path;
}
function runTestAutoLoader( $autoLoader = null ) {
$mwVendorPath = __DIR__ . '/../../../vendor/autoload.php';
$localVendorPath = __DIR__ . '/../vendor/autoload.php';
if ( is_readable( $localVendorPath ) ) {
$autoLoader = registerAutoloaderPath( 'local', $localVendorPath );
} elseif ( is_readable( $mwVendorPath ) ) {
$autoLoader = registerAutoloaderPath( 'MediaWiki', $mwVendorPath );
}
if ( $autoLoader instanceof \Composer\Autoload\ClassLoader ) {
return true;
}
return false;
}
if ( !runTestAutoLoader() ) {
die( 'The required test autoloader was not accessible' );
}

查看文件

@ -0,0 +1,51 @@
<?php
namespace SESP\Tests\Definition;
use SESP\Definition\DefinitionReader;
/**
* @covers \SESP\Definition\DefinitionReader
*
* @ingroup Test
*
* @group SESP
* @group SESPExtension
* @group mediawiki-databaseless
*
* @license GNU GPL v2+
* @since 1.1.1
*
* @author mwjames
*/
class DefinitionReaderTest extends \PHPUnit_Framework_TestCase {
public function testCanConstruct() {
$this->assertInstanceOf(
'\SESP\Definition\DefinitionReader',
new DefinitionReader
);
}
public function testDefaultDefinitionFileAvailability() {
$instance = new DefinitionReader;
$this->assertInternalType( 'array', $instance->getDefinitions() );
}
public function testInaccessibleJsonFileThrowsExeception() {
$this->setExpectedException( 'RuntimeException' );
$instance = new DefinitionReader( 'foo' );
$instance->getDefinitions();
}
public function testMalformedJsonFileThrowsException() {
$this->setExpectedException( 'UnexpectedValueException' );
$instance = new DefinitionReader( __DIR__ . '/../Fixture/malformed.json' );
$instance->getDefinitions();
}
}

查看文件

@ -2,6 +2,7 @@
namespace SESP\Tests;
use SESP\Definition\DefinitionReader;
use SESP\PropertyRegistry;
use SMW\DIProperty;
@ -14,6 +15,7 @@ use ReflectionClass;
*
* @group SESP
* @group SESPExtension
* @group mediawiki-databaseless
*
* @licence GNU GPL v2+
* @since 1.0
@ -29,44 +31,6 @@ class PropertyRegistryTest extends \PHPUnit_Framework_TestCase {
);
}
/**
* @depends testCanConstruct
*/
public function testJsonFileAvailability() {
$this->assertTrue( is_file( $this->getJsonFile() ) );
}
/**
* @depends testJsonFileAvailability
*/
public function testInaccessibleJsonFile() {
$this->setExpectedException( 'RuntimeException' );
PropertyRegistry::getInstance()->acquireDefinitionsFromJsonFile( 'foo.json' );
}
/**
* @depends testJsonFileAvailability
*/
public function testMalformedJsonFile() {
$this->setExpectedException( 'UnexpectedValueException' );
PropertyRegistry::getInstance()->acquireDefinitionsFromJsonFile( __DIR__ . '/' . 'malformed.json' );
}
/**
* @depends testJsonFileAvailability
*/
public function testAcquireDefinitionsFromJsonFile() {
$this->assertInternalType(
'array',
PropertyRegistry::getInstance()->acquireDefinitionsFromJsonFile( $this->getJsonFile() )
);
}
/**
* @depends testAcquireDefinitionsFromJsonFile
*/
public function testGetPropertyId() {
$this->assertInternalType(
'string',
@ -81,16 +45,10 @@ class PropertyRegistryTest extends \PHPUnit_Framework_TestCase {
);
}
/**
* @depends testGetPropertyId
*/
public function testGetPropertyIdWithUnknownIdentifier() {
$this->assertNull( PropertyRegistry::getInstance()->getPropertyId( 'Foo' ) );
}
/**
* @depends testAcquireDefinitionsFromJsonFile
*/
public function testGetPropertyType() {
$this->assertInternalType(
'integer',
@ -98,14 +56,10 @@ class PropertyRegistryTest extends \PHPUnit_Framework_TestCase {
);
}
/**
* @depends testGetPropertyType
*/
public function testGetPropertyTypeWithUnknownIdentifier() {
$this->assertNull( PropertyRegistry::getInstance()->getPropertyType( 'Foo' ) );
}
public function testRegisterPropertiesAndAliases() {
PropertyRegistry::clear();
$this->assertTrue( PropertyRegistry::getInstance()->registerPropertiesAndAliases() );
@ -153,7 +107,9 @@ class PropertyRegistryTest extends \PHPUnit_Framework_TestCase {
PropertyRegistry::clear();
$definitions = PropertyRegistry::getInstance()->acquireDefinitionsFromJsonFile( $this->getJsonFile() );
$definitionReader = new DefinitionReader;
$definitions = $definitionReader->getDefinitions();
$this->assertTrue( isset( $definitions['_EXIF'] ) );
unset( $definitions['_EXIF'] );
@ -250,9 +206,4 @@ class PropertyRegistryTest extends \PHPUnit_Framework_TestCase {
return $property;
}
protected function getJsonFile() {
return PropertyRegistry::getInstance()->getJsonFile();
}
}