diff --git a/libraries/cms/compatibility/compatibility.php b/libraries/cms/compatibility/compatibility.php new file mode 100644 index 0000000000000..51177e03d36ff --- /dev/null +++ b/libraries/cms/compatibility/compatibility.php @@ -0,0 +1,110 @@ + node. + * + * @return void + * + * @since 3.0.3 + */ + public function __construct(SimpleXMLElement $compatibilities) + { + $this->compatibilities = $compatibilities; + } + + /** + * Checks a version with a context. + * + * The way this method reads is: + * + * "Check the compatibilty of version, $version, with the context, $with". For example: + * "Check the compatibilty of version, '3.0.3' with 'joomla'." + * + * @param string $checkVersion The version number to compare against the compatibility specification. + * @param string $with The context of what we are testing compatibility with, for example "joomla". + * + * @return + * + * @since 3.0.3 + * @throws InvalidArgumentException if compatibility nodes are not found, or the 'with' argument does not match. + */ + public function check($checkVersion, $with = 'joomla') + { + $with = strtolower($with); + $node = $this->compatibilities->xpath("compatibility[@with='$with']"); + + if (empty($node)) + { + throw new InvalidArgumentException(sprintf('Compatibility with "%s" not found.', $with)); + } + + $include = $this->checkRules($node[0]->include, $checkVersion); + $exclude = $this->checkRules($node[0]->exclude, $checkVersion); + + return (boolean) ($include ^ $exclude); + } + + /** + * Checks a node with a collection tags against the check-version. + * + * If any matches are found, it will return true. + * + * @param SimpleXMLElement $rules + * @param string $checkVersion + * + * @return boolean + * + * @since 3.0.3 + */ + protected function checkRules(SimpleXMLElement $rules, $checkVersion) + { + $results = array(); + $versions = $rules->xpath('versions'); + + foreach ($versions as $version) + { + $from = (string) $version['from']; + $to = (string) $version['to']; + + if ($from && $to) + { + $results[] = version_compare($checkVersion, $from, 'ge') & version_compare($checkVersion, $to, 'le'); + } + else + { + if ($from) + { + $results[] = version_compare($checkVersion, $from, 'ge'); + } + else + { + $results[] = version_compare($checkVersion, $to, 'le'); + } + } + } + + return in_array(true, $results); + } + +} diff --git a/tests/unit/suites/cms/compatibility/compatibilityTest.php b/tests/unit/suites/cms/compatibility/compatibilityTest.php new file mode 100644 index 0000000000000..2501e94ff5727 --- /dev/null +++ b/tests/unit/suites/cms/compatibility/compatibilityTest.php @@ -0,0 +1,188 @@ + array(true, '2.5', 'joomla'), + 'Joomla - too low' => array(false, '2.4', 'joomla'), + 'Joomla - too high' => array(false, '3', 'joomla'), + 'Joomla - exclude left edge fail' => array(false, '2.5.1', 'joomla'), + 'Joomla - exclude right edge fail' => array(false, '2.5.3', 'joomla'), + 'Joomla - exclude right edge pass' => array(true, '2.5.4', 'joomla'), + 'PHP - pass' => array(true, '5.4', 'PHP'), + 'PHP - fail' => array(false, '5.2', 'php'), + 'com_foo - pass' => array(true, '0.0.1', 'com_foo'), + 'com_foo - fail' => array(false, '1.2.4', 'com_FOO'), + ); + } + + /** + * Seeds the testCheckRules method. + * + * @return array + * + * @since 3.0.3 + */ + public function seedCheckRules() + { + return array( + 'From only - left edge' => array( + true, + '', + '2.5.8' + ), + 'From only - too low' => array( + false, + '', + '2.5.7' + ), + 'To only - left edge' => array( + true, + '', + '2.5.8' + ), + 'To only - too low' => array( + false, + '', + '2.5.9' + ), + 'Single - left edge' => array( + true, + '', + '2.5.8' + ), + 'Single - right edge' => array( + true, + '', + '2.5.99' + ), + 'Single - too low' => array( + false, + '', + '2.5.7' + ), + 'Single - too high' => array( + false, + '', + '2.5.100' + ), + 'Multiple - passes' => array( + true, + '', + '3.0.1' + ), + 'Multiple - fails' => array( + false, + '', + '2.5.7' + ), + ); + } + + /** + * Checks the __construct method. + * + * @return void + * + * @covers JCompatibility::__construct + * @since 3.0.3 + */ + public function test__construct() + { + $this->assertAttributeNotEmpty('compatibilities', $this->_instance); + } + + /** + * Checks the check method. + * + * @param boolean $expected The expected result from the check method. + * @param string $version The version number to check. + * @param string $with The context of the check (compare 'with'). + * + * @return void + * + * @covers JCompatibility::check + * @dataProvider seedCheck + * @since 3.0.3 + */ + public function testCheck($expected, $version, $with) + { + $this->assertEquals($expected, $this->_instance->check($version, $with)); + } + + /** + * Checks the check method with an expected exception. + * + * @return void + * + * @covers JCompatibility::check + * @expectedException InvalidArgumentException + * @since 3.0.3 + */ + public function testCheck_exception() + { + $this->_instance->check('1', 'foobar'); + } + + /** + * Checks the checkRules method. + * + * @param boolean $expected The expected result from the checkRules method. + * @param string $data The XML data for the versions tags. + * @param string $version The version number to check. + * + * @return void + * + * @covers JCompatibility::checkRules + * @dataProvider seedCheckRules + * @since 3.0.3 + */ + public function testCheckRules($expected, $data, $version) + { + $xml = new SimpleXMLElement('' . $data . ''); + $this->assertEquals($expected, TestReflection::invoke($this->_instance, 'checkRules', $xml, $version)); + } + + /** + * Sets up the fixture. This method is called before a test is executed. + * + * @return void + * + * @since 3.0.3 + */ + protected function setUp() + { + $data = file_get_contents(__DIR__ . '/compatibilityTest.xml'); + $xml = new SimpleXMLElement($data); + $this->_instance = new JCompatibility($xml->compatibilities); + } +} diff --git a/tests/unit/suites/cms/compatibility/compatibilityTest.xml b/tests/unit/suites/cms/compatibility/compatibilityTest.xml new file mode 100644 index 0000000000000..c1726438694ac --- /dev/null +++ b/tests/unit/suites/cms/compatibility/compatibilityTest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file