Commit 6da9ba41 authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

+ Added compatibility with PHPUnit 3.6.x + Added new feature for checking...

+ Added compatibility with PHPUnit 3.6.x + Added new feature for checking setup scripts versions sequance
parent 46e3464e
...@@ -8,7 +8,7 @@ This extension was created especially for resolving this problem and promoting t ...@@ -8,7 +8,7 @@ This extension was created especially for resolving this problem and promoting t
System Requirements System Requirements
------------------- -------------------
* PHP 5.3 or higher * PHP 5.3 or higher
* PHPUnit 3.5 * PHPUnit 3.6.x
* Magento CE1.4.x-1.5.x/PE1.9.x-PE1.10.x/EE1.9.x-1.10.x * Magento CE1.4.x-1.5.x/PE1.9.x-PE1.10.x/EE1.9.x-1.10.x
Documentation Documentation
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*/ */
// Loading Spyc yaml parser, // Loading Spyc yaml parser,
// becuase Symfony component is not working propertly with nested // because Symfony component is not working properly with nested structures
require_once 'Spyc/spyc.php'; require_once 'Spyc/spyc.php';
/** /**
...@@ -140,7 +140,7 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -140,7 +140,7 @@ class EcomDev_PHPUnit_Model_Fixture
/** /**
* Model constuctor, just defines wich resource model to use * Model constructor, just defines which resource model to use
* (non-PHPdoc) * (non-PHPdoc)
* @see Varien_Object::_construct() * @see Varien_Object::_construct()
*/ */
...@@ -162,7 +162,7 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -162,7 +162,7 @@ class EcomDev_PHPUnit_Model_Fixture
} }
/** /**
* Sets storage for fixutures * Sets storage for fixtures
* *
* @param Varien_Object $storage * @param Varien_Object $storage
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
......
...@@ -72,11 +72,35 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas ...@@ -72,11 +72,35 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas
* @param string|null $expectedValue * @param string|null $expectedValue
* @return EcomDev_PHPUnit_Constraint_Config * @return EcomDev_PHPUnit_Constraint_Config
*/ */
public static function configResource($moduleName, $type = EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_DEFINED, $expectedValue = null) public static function configResource($moduleName,
$type = EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_DEFINED,
$expectedValue = null)
{ {
return self::config( return self::config(
new EcomDev_PHPUnit_Constraint_Config_Resource($moduleName, $type, self::app()->getConfig()->getModuleDir('', $moduleName), $expectedValue) new EcomDev_PHPUnit_Constraint_Config_Resource($moduleName, $type,
self::app()->getConfig()->getModuleDir('', $moduleName),
$expectedValue)
);
}
/**
* A new constraint for checking resource setup scripts consistency
*
* @param string $moduleName
* @param string $type
* @param array|null $expectedValue
* @param string $resourceName
* @return EcomDev_PHPUnit_Constraint_Config
*/
public static function configResourceScript($moduleName,
$type = EcomDev_PHPUnit_Constraint_Config_Resource_Script::TYPE_SCRIPT_SCHEME,
array $expectedValue = null, $resourceName = null)
{
return self::config(
new EcomDev_PHPUnit_Constraint_Config_Resource_Script($moduleName, $type,
self::app()->getConfig()->getModuleDir('', $moduleName),
$resourceName, $expectedValue)
); );
} }
...@@ -210,7 +234,7 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas ...@@ -210,7 +234,7 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas
$message $message
); );
} }
/** /**
* Asserts that config resource for module is defined and directory with the same name exists in module * Asserts that config resource for module is defined and directory with the same name exists in module
* *
...@@ -219,19 +243,19 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas ...@@ -219,19 +243,19 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas
* @param mixed $expectedResourceName * @param mixed $expectedResourceName
* @param string $message * @param string $message
*/ */
public static function assertSetupResourceExists($moduleName = null, $expectedResourceName = null, $message = '') public static function assertSchemeSetupExists($moduleName = null, $expectedResourceName = null, $message = '')
{ {
if ($moduleName === null) { if ($moduleName === null) {
$moduleName = self::getModuleNameFromCallStack(); $moduleName = self::getModuleNameFromCallStack();
} }
self::assertThatConfig( self::assertThatConfig(
self::configResource($moduleName, self::configResource($moduleName,
EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_EXISTS, EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_SCHEME_EXISTS,
$expectedResourceName), $expectedResourceName),
$message $message
); );
} }
/** /**
* Asserts that config resource for module is defined and directory with the same name exists in module * Asserts that config resource for module is defined and directory with the same name exists in module
* *
...@@ -240,20 +264,161 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas ...@@ -240,20 +264,161 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas
* @param mixed $expectedResourceName * @param mixed $expectedResourceName
* @param string $message * @param string $message
*/ */
public static function assertSetupResourceNotExists($moduleName = null, $expectedResourceName = null, $message = '') public static function assertSchemeSetupNotExists($moduleName = null, $expectedResourceName = null, $message = '')
{ {
if ($moduleName === null) { if ($moduleName === null) {
$moduleName = self::getModuleNameFromCallStack(); $moduleName = self::getModuleNameFromCallStack();
} }
self::assertThatConfig( self::assertThatConfig(
self::logicalNot( self::logicalNot(
self::configResource($moduleName, self::configResource($moduleName,
EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_EXISTS, EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_SCHEME_EXISTS,
$expectedResourceName) $expectedResourceName)
),
$message
);
}
/**
* Asserts that config resource for module is defined and directory with the same name exists in module directory
* for data setup scripts
*
*
* @param string $moduleName
* @param mixed $expectedResourceName
* @param string $message
*/
public static function assertDataSetupExists($moduleName = null, $expectedResourceName = null, $message = '')
{
if ($moduleName === null) {
$moduleName = self::getModuleNameFromCallStack();
}
self::assertThatConfig(
self::configResource($moduleName,
EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_DATA_EXISTS,
$expectedResourceName),
$message
);
}
/**
* Asserts that config resource for module is defined and directory with the same name exists in module
* directory for data setup scripts
*
* @param string $moduleName
* @param mixed $expectedResourceName
* @param string $message
*/
public static function assertDataSetupNotExists($moduleName = null, $expectedResourceName = null, $message = '')
{
if ($moduleName === null) {
$moduleName = self::getModuleNameFromCallStack();
}
self::assertThatConfig(
self::logicalNot(
self::configResource($moduleName,
EcomDev_PHPUnit_Constraint_Config_Resource::TYPE_SETUP_DATA_EXISTS,
$expectedResourceName)
),
$message
);
}
/**
* Asserts that there is defined properly list of data/scheme upgrade scripts
*
* @param string $type
* @param string|null $from
* @param string|null $to
* @param string|null $moduleName
* @param string|null $moduleName
* @param mixed $expectedResourceName
* @param string $message
*/
public static function assertSetupScriptVersions(
$type = EcomDev_PHPUnit_Constraint_Config_Resource_Script::TYPE_SCRIPT_SCHEME, $from = null, $to = null,
$moduleName = null, $resourceName = null,$message = '')
{
if ($moduleName === null) {
$moduleName = self::getModuleNameFromCallStack();
}
if ($to === null) {
$moduleConfig = self::app()->getConfig()->getModuleConfig($moduleName);
if (isset($moduleConfig->version)) {
$to = (string)$moduleConfig->version;
}
}
self::assertThatConfig(
self::configResourceScript($moduleName,
$type,
array($from, $to),
$resourceName
), ),
$message $message
); );
} }
/**
* Asserts that there is defined properly list of scheme upgrade scripts
*
* @param string|null $from
* @param string|null $to
* @param string|null $moduleName
* @param string|null $moduleName
* @param mixed $expectedResourceName
* @param string $message
*/
public static function assertSchemeSetupScriptVersions($from = null, $to = null,
$moduleName = null, $resourceName = null,$message = '')
{
self::assertSetupScriptVersions(EcomDev_PHPUnit_Constraint_Config_Resource_Script::TYPE_SCRIPT_SCHEME, $from,
$to, $moduleName, $resourceName, $message);
}
/**
* Asserts that there is defined properly list of data upgrade scripts
*
* @param string|null $from
* @param string|null $to
* @param string|null $moduleName
* @param string|null $moduleName
* @param mixed $expectedResourceName
* @param string $message
*/
public static function assertDataSetupScriptVersions($from = null, $to = null,
$moduleName = null, $resourceName = null,$message = '')
{
self::assertSetupScriptVersions(EcomDev_PHPUnit_Constraint_Config_Resource_Script::TYPE_SCRIPT_DATA, $from,
$to, $moduleName, $resourceName, $message);
}
/**
* Alias of assertSchemeSetupExists() model
*
*
* @param string $moduleName
* @param mixed $expectedResourceName
* @param string $message
*/
public static function assertSetupResourceExists($moduleName = null, $expectedResourceName = null, $message = '')
{
self::assertSchemeSetupExists($moduleName, $expectedResourceName, $message);
}
/**
* Alias of assertSchemeSetupNotExists() model
*
*
* @param string $moduleName
* @param mixed $expectedResourceName
* @param string $message
*/
public static function assertSetupResourceNotExists($moduleName = null, $expectedResourceName = null, $message = '')
{
self::assertSchemeSetupNotExists($moduleName, $expectedResourceName, $message);
}
/** /**
* Asserts that config node value is equal to the expected value. * Asserts that config node value is equal to the expected value.
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* Abstract constraint for EcomDev_PHPUnit constraints * Abstract constraint for EcomDev_PHPUnit constraints
* Contains flexible constaint types implementation * Contains flexible constaint types implementation
* *
* @todo refactor failures for being 100% compatible with PHPUnit 3.6
*/ */
abstract class EcomDev_PHPUnit_Constraint_Abstract abstract class EcomDev_PHPUnit_Constraint_Abstract
extends PHPUnit_Framework_Constraint extends PHPUnit_Framework_Constraint
...@@ -187,7 +188,12 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract ...@@ -187,7 +188,12 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
if (in_array($this->_type, $this->_typesWithDiff)) { if (in_array($this->_type, $this->_typesWithDiff)) {
throw new EcomDev_PHPUnit_Constraint_Exception( throw new EcomDev_PHPUnit_Constraint_Exception(
$failureDescription, $failureDescription,
PHPUnit_Util_Diff::diff($this->getExpectedValue(), $this->getActualValue($other)), new PHPUnit_Framework_ComparisonFailure(
$this->getExpectedValue(),
$this->getActualValue($other),
$this->getExpectedValue(),
$this->getActualValue($other)
),
$description $description
); );
} else { } else {
...@@ -197,6 +203,23 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract ...@@ -197,6 +203,23 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
} }
} }
/**
* Adds compatibility to PHPUnit 3.6
*
* @param mixed $other
* @param mixed $description (custom description)
* @param boolean $not
* @return string
*/
protected function failureDescription($other, $description, $not)
{
if (method_exists($this, 'customFailureDescription')) {
return $this->customFailureDescription($other, $description, $not);
}
return parent::failureDescription($other, $description, $not);
}
/** /**
* Returns a scalar representation of actual value, * Returns a scalar representation of actual value,
* Returns $other if internal acutal value is not set * Returns $other if internal acutal value is not set
...@@ -216,7 +239,7 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract ...@@ -216,7 +239,7 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
/** /**
* Returns a scalar representation of expected value * Returns a scalar representation of expected value
* *
* @return string * @return scalar
*/ */
protected function getExpectedValue() protected function getExpectedValue()
{ {
......
...@@ -92,11 +92,11 @@ class EcomDev_PHPUnit_Constraint_Config extends PHPUnit_Framework_Constraint ...@@ -92,11 +92,11 @@ class EcomDev_PHPUnit_Constraint_Config extends PHPUnit_Framework_Constraint
* @param Varien_Simplexml_Config $config * @param Varien_Simplexml_Config $config
* @see PHPUnit_Framework_Constraint::evaluate() * @see PHPUnit_Framework_Constraint::evaluate()
*/ */
public function evaluate($config) public function evaluate($config, $description = '', $returnResult = false)
{ {
$nodeValue = $this->getNodeValue($config); $nodeValue = $this->getNodeValue($config);
return $this->constraint->evaluate($nodeValue); return $this->constraint->evaluate($nodeValue, $description, $returnResult);
} }
/** /**
......
...@@ -65,14 +65,14 @@ abstract class EcomDev_PHPUnit_Constraint_Config_Abstract ...@@ -65,14 +65,14 @@ abstract class EcomDev_PHPUnit_Constraint_Config_Abstract
* (non-PHPdoc) * (non-PHPdoc)
* @see EcomDev_PHPUnit_Constraint_Abstract::evaluate() * @see EcomDev_PHPUnit_Constraint_Abstract::evaluate()
*/ */
public function evaluate($other) public function evaluate($other, $description = '', $returnResult = false)
{ {
if ($other === false) { if ($other === false) {
// If node was not found, than evaluation fails // If node was not found, than evaluation fails
return false; return false;
} }
return parent::evaluate($other); return parent::evaluate($other, $description, $returnResult);
} }
......
<?php <?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/** /**
* Setup resources configuration constraint * Setup resources configuration constraint
* *
...@@ -9,7 +26,8 @@ class EcomDev_PHPUnit_Constraint_Config_Resource ...@@ -9,7 +26,8 @@ class EcomDev_PHPUnit_Constraint_Config_Resource
const XML_PATH_RESOURCES_NODE = 'global/resources'; const XML_PATH_RESOURCES_NODE = 'global/resources';
const TYPE_SETUP_DEFINED = 'setup_defined'; const TYPE_SETUP_DEFINED = 'setup_defined';
const TYPE_SETUP_EXISTS = 'setup_exists'; const TYPE_SETUP_SCHEME_EXISTS = 'setup_scheme_exists';
const TYPE_SETUP_DATA_EXISTS = 'setup_data_exists';
/** /**
* Name of the module for constraint * Name of the module for constraint
...@@ -26,7 +44,7 @@ class EcomDev_PHPUnit_Constraint_Config_Resource ...@@ -26,7 +44,7 @@ class EcomDev_PHPUnit_Constraint_Config_Resource
protected $_moduleDirectory = null; protected $_moduleDirectory = null;
/** /**
* Contraint for evaluation of module config node * Constraint for evaluation of module config node
* *
* @param string $nodePath * @param string $nodePath
* @param string $type * @param string $type
...@@ -37,11 +55,13 @@ class EcomDev_PHPUnit_Constraint_Config_Resource ...@@ -37,11 +55,13 @@ class EcomDev_PHPUnit_Constraint_Config_Resource
{ {
$this->_expectedValueValidation += array( $this->_expectedValueValidation += array(
self::TYPE_SETUP_DEFINED => array(false, 'is_string', 'string'), self::TYPE_SETUP_DEFINED => array(false, 'is_string', 'string'),
self::TYPE_SETUP_EXISTS => array(false, 'is_string', 'string'), self::TYPE_SETUP_SCHEME_EXISTS => array(false, 'is_string', 'string'),
self::TYPE_SETUP_DATA_EXISTS => array(false, 'is_string', 'string'),
); );
$this->_typesWithDiff[] = self::TYPE_SETUP_DEFINED; $this->_typesWithDiff[] = self::TYPE_SETUP_DEFINED;
$this->_typesWithDiff[] = self::TYPE_SETUP_EXISTS; $this->_typesWithDiff[] = self::TYPE_SETUP_SCHEME_EXISTS;
$this->_typesWithDiff[] = self::TYPE_SETUP_DATA_EXISTS;
parent::__construct( parent::__construct(
self::XML_PATH_RESOURCES_NODE, self::XML_PATH_RESOURCES_NODE,
...@@ -52,7 +72,7 @@ class EcomDev_PHPUnit_Constraint_Config_Resource ...@@ -52,7 +72,7 @@ class EcomDev_PHPUnit_Constraint_Config_Resource
$this->_moduleName = $moduleName; $this->_moduleName = $moduleName;
$this->_moduleDirectory = $moduleDirectory; $this->_moduleDirectory = $moduleDirectory;
if ($this->_type === self::TYPE_SETUP_EXISTS if (($this->_type === self::TYPE_SETUP_SCHEME_EXISTS || $this->_type === self::TYPE_SETUP_DATA_EXISTS)
&& !is_dir($moduleDirectory)) { && !is_dir($moduleDirectory)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'real directory', $moduleDirectory); throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'real directory', $moduleDirectory);
} }
...@@ -98,21 +118,51 @@ class EcomDev_PHPUnit_Constraint_Config_Resource ...@@ -98,21 +118,51 @@ class EcomDev_PHPUnit_Constraint_Config_Resource
} }
/** /**
* Represents contraint for definition of setup resources * Represents constraint for definition of setup resources
* *
* @return string * @return string
*/ */
public function textSetupDefined() public function textSetupDefined()
{ {
return sprintf('contains resource definition for %s module with %s name', $this->_moduleName, $this->_expectedValue); return sprintf('contains resource definition for %s module with %s name',
$this->_moduleName, $this->_expectedValue);
} }
/** /**
* Checks existanse and definition of expected resource name * Set actual value for comparison from module sql/data directories
*
* @param string $type
* @return EcomDev_PHPUnit_Constraint_Config_Resource
*/
protected function setActualValueFromResourceDirectories($type = 'sql')
{
if (!is_dir($this->_moduleDirectory . DIRECTORY_SEPARATOR . $type)) {
$this->setActualValue(array());
return $this;
}
$dirIterator = new DirectoryIterator($this->_moduleDirectory . DIRECTORY_SEPARATOR . $type);
$resourceDirectories = array();
foreach ($dirIterator as $entry) {
/* @var $entry DirectoryIterator */
if ($entry->isDir() && !$entry->isDot()) {
$resourceDirectories[] = $entry->getBasename();
}
}
$this->setActualValue($resourceDirectories);
return $this;
}
/**
* Checks existence and definition of expected resource name schema directory
* *
* @param Varien_Simplexml_Element $other * @param Varien_Simplexml_Element $other
*/ */
protected function evaluateSetupExists($other) protected function evaluateSetupSchemeExists($other)
{ {
$moduleResources = $this->getModuleSetupResources($other); $moduleResources = $this->getModuleSetupResources($other);
...@@ -122,35 +172,52 @@ class EcomDev_PHPUnit_Constraint_Config_Resource ...@@ -122,35 +172,52 @@ class EcomDev_PHPUnit_Constraint_Config_Resource
current($moduleResources); current($moduleResources);
} }
if (!is_dir($this->_moduleDirectory . DIRECTORY_SEPARATOR . 'sql')) { $this->setActualValueFromResourceDirectories('sql');
$this->setActualValue(array());
return false;
}
$dirIterator = new DirectoryIterator($this->_moduleDirectory . DIRECTORY_SEPARATOR . 'sql');
$resourceDirectories = array(); return in_array($this->_expectedValue, $moduleResources)
&& in_array($this->_expectedValue, $this->_actualValue);
}
/**
* Represents constraint for definition of setup resources
*
* @return string
*/
public function textSetupSchemeExists()
{
return sprintf(' schema directory is created for %s module with %s name',
$this->_moduleName, $this->_expectedValue);
}
/**
* Checks existence and definition of expected resource name data directory
*
* @param Varien_Simplexml_Element $other
*/
protected function evaluateSetupDataExists($other)
{
$moduleResources = $this->getModuleSetupResources($other);
foreach ($dirIterator as $entry) { if ($this->_expectedValue === null) {
if ($entry->isDir() && !$entry->isDot()) { $this->_expectedValue = empty($moduleResources) ?
$resourceDirectories[] = $entry->getBasename(); strtolower($this->_moduleName) . '_setup' :
} current($moduleResources);
} }
$this->setActualValue($resourceDirectories); $this->setActualValueFromResourceDirectories('data');
return in_array($this->_expectedValue, $moduleResources) return in_array($this->_expectedValue, $moduleResources)
&& in_array($this->_expectedValue, $this->_actualValue); && in_array($this->_expectedValue, $this->_actualValue);
} }
/** /**
* Represents contraint for definition of setup resources * Represents constraint for definition of setup resources
* *
* @return string * @return string
*/ */
public function textSetupExists() public function textSetupDataExists()
{ {
return sprintf('are defined or created directory for it in sql one of %s module with %s name', $this->_moduleName, $this->_expectedValue); return sprintf(' data directory is created for %s module with %s name', $this->_moduleName, $this->_expectedValue);
} }
/** /**
...@@ -166,3 +233,4 @@ class EcomDev_PHPUnit_Constraint_Config_Resource ...@@ -166,3 +233,4 @@ class EcomDev_PHPUnit_Constraint_Config_Resource
); );
} }
} }
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Setup resources configuration constraint
*
*/
class EcomDev_PHPUnit_Constraint_Config_Resource_Script
extends EcomDev_PHPUnit_Constraint_Config_Abstract
{
const XML_PATH_RESOURCES_NODE = 'global/resources';
const TYPE_SCRIPT_SCHEME = 'script_scheme';
const TYPE_SCRIPT_DATA = 'script_data';
const FILE_INSTALL_SCHEME = '/^(mysql4-install|install)-([\\d\\.]+)$/';
const FILE_UPGRADE_SCHEME = '/^(mysql4-upgrade|upgrade)-([\\d\\.]+)-([\\d\\.]+)$/';
const FILE_INSTALL_DATA = '/^(mysql4-data-install|data-install)-([\\d\\.]+)$/';
const FILE_UPGRADE_DATA = '/^(mysql4-data-upgrade|data-upgrade)-([\\d\\.]+)-([\\d\\.]+)$/';
/**
* Name of the module for constraint
*
* @var string
*/
protected $_moduleName = null;
/**
* The module directory for constraint
*
* @var string
*/
protected $_moduleDirectory = null;
/**
* Resource name where to look for scripts
*
* @var string
*/
protected $_resourceName = null;
/**
* Contraint for evaluation of module config node
*
* @param string $nodePath
* @param string $type
* @param string $moduleDirectory
* @param mixed $expectedValue
*/
public function __construct($moduleName, $type, $moduleDirectory, $resourceName = null, $expectedVersions = null)
{
$this->_typesWithDiff[] = self::TYPE_SCRIPT_SCHEME;
$this->_typesWithDiff[] = self::TYPE_SCRIPT_DATA;
parent::__construct(
self::XML_PATH_RESOURCES_NODE,
$type,
$expectedVersions
);
$this->_moduleName = $moduleName;
$this->_moduleDirectory = $moduleDirectory;
$this->_resourceName = $resourceName;
if (!is_dir($moduleDirectory)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'real directory', $moduleDirectory);
}
}
/**
* Returns setup resource for module setup scripts
*
* @param Varien_Simplexml_Element $xml
* @return string
*/
protected function getResourceName(Varien_Simplexml_Element $xml)
{
foreach ($xml->children() as $resourceNode) {
if (isset($resourceNode->setup->module)
&& (string)$resourceNode->setup->module === $this->_moduleName) {
return $resourceNode->getName();
}
}
return false;
}
/**
* Returns list of scripts that are presented in resource directory
*
* @param string|array $directory
* @param string $fromVersion
*/
protected function parseVersions($directory)
{
if (is_array($directory)) {
// For multiple directories merge result together
$result = array();
foreach ($directory as $entry) {
$result = array_merge_recursive($result, $this->parseVersions($entry));
}
// Sort install scripts by version
usort($result['install'], array($this, 'compareVersions'));
// Sort upgrade scripts by version
usort($result['upgrade'], array($this, 'compareVersions'));
return $result;
}
$versions = array(
'scheme' => array(
'install' => array(),
'upgrade' => array()
),
'data' => array(
'install' => array(),
'upgrade' => array()
)
);
if (!is_dir($directory)) {
return $versions;
}
$directoryIterator = new DirectoryIterator($directory);
$matchMap = array(
self::FILE_INSTALL_SCHEME => array('scheme', 'install'),
self::FILE_UPGRADE_SCHEME => array('scheme', 'upgrade'),
self::FILE_INSTALL_DATA => array('data', 'install'),
self::FILE_UPGRADE_DATA => array('data', 'upgrade')
);
foreach ($directoryIterator as $entry) {
/* @var $entry SplFileInfo */
// We do not support scheme upgrade scripts with .sql
// file extension, since it is not the best practice.
if ($entry->isFile() && substr($entry->getBasename(), -4) === '.php') {
foreach ($matchMap as $pattern => $target) {
// Fulfill versions array
if (preg_match($pattern, $entry->getBasename('.php'), $match)) {
$versions[$target[0]][$target[1]][] = array(
'filename' => $entry->getBasename(),
'prefix' => $match[1],
'from' => $match[2],
'to' => isset($match[3]) ? $match[3] : null
);
}
}
}
}
return $versions;
}
/**
* Compares two versions array
*
* @param array $first
* @param array $next
* @return int
*/
protected function compareVersions($first, $next)
{
$result = version_compare($first['from'], $next['from']);
if ($result === 0) {
/* if file with type specified, it has more priority */
$result = (strpos($first['prefix'], 'mysql4') ? 1 : -1);
}
return $result;
}
/**
* Returns list of version scripts including expected and actual information
*
* @param array $versions
* @param string $from
* @param string $to
* @param string $scriptPrefix
* @return array with keys expected and actual
*/
protected function getVersionScriptsDiff($versions, $from = null, $to = null, $scriptPrefix = '')
{
if ($from === null && end($versions['install'])) {
$version = end($versions['install']);
$from = $version['from'];
reset($versions['install']);
} elseif ($from === null && reset($versions['upgrade'])) {
$version = reset($versions['upgrade']);
$from = $version['from'];
}
if ($to === null && end($versions['upgrade'])) {
$version = end($versions['upgrade']);
$to = $version['to'];
} elseif ($to === null) {
$to = $from;
}
$actualVersions = array();
$expectedVersions = array();
$latestVersionFound = null;
if (empty($versions['install']) && $from !== null) {
$expectedVersions[] = sprintf('install-%s.php', $scriptPrefix, $from);
$latestVersionFound = $from;
} elseif ($from !== null) {
foreach ($versions['install'] as $index=>$version) {
if (version_compare($version['from'], $from) <= 0
&& (!isset($versions['install'][$index+1]['from'])
|| version_compare($versions['install'][$index+1]['from'], $from) > 0)) {
$latestVersionFound = $version['from'];
$actualVersions[] = $version['filename'];
$expectedVersions[] = $version['filename'];
break;
}
}
} elseif (!empty($versions['install'])) {
$version = current($versions['install']);
$latestVersionFound = $version['from'];
$actualVersions[] = $version['filename'];
$expectedVersions[] = $version['filename'];
} else {
$expectedVersions[] = sprintf('%sinstall-%s.php', $scriptPrefix, $to);
$latestVersionFound = $to;
}
foreach ($versions['upgrade'] as $version) {
$fromCompare = version_compare($version['from'], $latestVersionFound);
if ($fromCompare < 0) {
continue;
}
if ($fromCompare > 0) {
$expectedVersions[] = sprintf('%supgrade-%s-%s.php', $scriptPrefix, $latestVersionFound, $version['from']);
}
$actualVersions[] = $version['filename'];
$expectedVersions[] = $version['filename'];
$latestVersionFound = $version['to'];
}
if ($to !== null && version_compare($latestVersionFound, $to) === -1) {
$expectedVersions[] = sprintf('%supgrade-%s-%s.php', $scriptPrefix, $latestVersionFound, $to);
} elseif ($to !== null && version_compare($latestVersionFound, $to) === 1 && $expectedVersions) {
array_pop($expectedVersions);
}
return array(
'actual' => $actualVersions,
'expected' => $expectedVersions
);
}
/**
* Checks structure of the schme setup scripts for a module
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateScriptScheme($other)
{
if ($this->_resourceName === null) {
$this->_resourceName = $this->getResourceName($other);
}
$from = isset($this->_expectedValue[0]) ? $this->_expectedValue[0] : null;
$to = isset($this->_expectedValue[1]) ? $this->_expectedValue[1] : null;
$versions = $this->parseVersions(
$this->_moduleDirectory . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . $this->_resourceName
);
$diff = $this->getVersionScriptsDiff($versions['scheme'], $from, $to);
$this->setActualValue($diff['actual']);
$this->_expectedValue = $diff['expected'];
return $this->_actualValue == $this->_expectedValue;
}
/**
* Text represetnation of scheme setup scripts versions chain
*
* @return
*/
public function textScriptScheme()
{
return 'scheme setup scripts are created in correct version chain order';
}
/**
* Checks structure of the data setup scripts for a module
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateScriptData($other)
{
if ($this->_resourceName === null) {
$this->_resourceName = $this->getResourceName($other);
}
$from = isset($this->_expectedValue[0]) ? $this->_expectedValue[0] : null;
$to = isset($this->_expectedValue[1]) ? $this->_expectedValue[1] : null;
$versions = $this->parseVersions(
array(
$this->_moduleDirectory . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $this->_resourceName,
$this->_moduleDirectory . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . $this->_resourceName
)
);
$diff = $this->getVersionScriptsDiff($versions['data'], $from, $to);
$this->setActualValue($diff['actual']);
$this->_expectedValue = $diff['expected'];
return $this->_actualValue == $this->_expectedValue;
}
/**
* Text represetnation of scheme setup scripts versions chain
*
* @return
*/
public function textScriptData()
{
return 'data setup scripts are created in correct version chain order';
}
/**
* Custom failure description for showing config related errors
* (non-PHPdoc)
* @see PHPUnit_Framework_Constraint::customFailureDescription()
*/
protected function customFailureDescription($other, $description, $not)
{
return sprintf(
'Failed asserting that setup resources %s.',
$this->toString()
);
}
}
...@@ -27,12 +27,16 @@ class EcomDev_PHPUnit_Constraint_Exception extends PHPUnit_Framework_Expectation ...@@ -27,12 +27,16 @@ class EcomDev_PHPUnit_Constraint_Exception extends PHPUnit_Framework_Expectation
public function __construct($description, $diff = '', $message = '') public function __construct($description, $diff = '', $message = '')
{ {
if (!is_scalar($diff)) { if (!$diff instanceof PHPUnit_Framework_ComparisonFailure) {
$diff = print_r($diff, true); if (!is_scalar($diff)) {
$diff = print_r($diff, true);
}
$this->diff = $diff;
$diff = null;
} }
$this->diff = $diff; parent::__construct($message, $diff);
parent::__construct($description, null, $message);
} }
public function toString() public function toString()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment