We will work on Apr 26th (Saturday) and will be off from Apr 30th (Wednesday) until May 2nd (Friday) for public holiday in our country

Commit 00008320 authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

+ Added new configuration test case

+ Added constraints for configuration node asserting, module nodes assertions.
parent 431c3a29
......@@ -94,6 +94,13 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
*/
protected $_eventsEnabled = true;
/**
* List of module names stored by class name
*
* @var array
*/
protected $_moduleNameByClassName = array();
/**
* This method replaces application, event and config objects
* in Mage to perform unit tests in separate Magento steam
......@@ -105,7 +112,7 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
self::$_oldApplication = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_app');
self::$_oldConfig = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_config');
self::$_oldEventCollection = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_events');
self::$_oldEventCollection = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_registry');
self::$_oldRegistry = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_registry');
// Setting environment variables for unit tests
......@@ -196,6 +203,54 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
EcomDev_Utils_Reflection::setRestrictedPropertyValue('Mage', '_registry', self::$_oldRegistry);
}
/**
* Returns module name for a particular object
*
* @param string|object $className
* @throws RuntimeException if module name was not found for the passed class name
* @return string
*/
public function getModuleNameByClassName($className)
{
if (is_object($className)) {
$className = get_class($className);
}
if (!isset($this->_moduleNameByClassName[$className])) {
// Try to find the module name by class name
$moduleName = false;
foreach ($this->getConfig()->getNode('modules')->children() as $module) {
if (strpos($className, $module->getName()) === 0) {
$moduleName = $module->getName();
break;
}
}
if (!$moduleName) {
throw new RuntimeException('Cannot to find the module name for class name: ' . $className);
}
$this->setModuleNameForClassName($className, $moduleName);
}
return $this->_moduleNameByClassName[$className];
}
/**
* Set associated module name for a class name,
* Usually used for making possible dependency injection in the test cases
*
*
* @param string $className
* @param string $moduleName
* @return EcomDev_PHPUnit_Model_App
*/
public function setModuleNameForClassName($className, $moduleName)
{
$this->_moduleNameByClassName[$className] = $moduleName;
return $this;
}
/**
* Disables events fire
*
......
......@@ -89,7 +89,7 @@ class EcomDev_PHPUnit_Model_Config extends Mage_Core_Model_Config
public function getModelInstance($modelClass='', $constructArguments=array())
{
if (!isset($this->_replaceInstanceCreation['model'][$modelClass])) {
return parent::getModelInstance($modelClass='', $constructArguments=array());
return parent::getModelInstance($modelClass, $constructArguments);
}
return $this->_replaceInstanceCreation['model'][$modelClass];
......@@ -104,7 +104,7 @@ class EcomDev_PHPUnit_Model_Config extends Mage_Core_Model_Config
public function getResourceModelInstance($modelClass='', $constructArguments=array())
{
if (!isset($this->_replaceInstanceCreation['resource_model'][$modelClass])) {
return parent::getResourceModelInstance($modelClass='', $constructArguments=array());
return parent::getResourceModelInstance($modelClass, $constructArguments);
}
return $this->_replaceInstanceCreation['resource_model'][$modelClass];
......
......@@ -29,7 +29,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
{
const XML_PATH_DEFAULT_FIXTURE_MODEL = 'phpunit/suite/fixture/model';
const XML_PATH_DEFAULT_EXPECTATION_MODEL = 'phpunit/suite/expectatio/model';
const XML_PATH_DEFAULT_EXPECTATION_MODEL = 'phpunit/suite/expectation/model';
/**
......@@ -55,6 +55,37 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
protected $_originalStore = null;
/**
* Retrieves the module name for current test case
*
* @return string
* @throws RuntimeException if module name was not found for the passed class name
*/
public function getModuleName()
{
return Mage::app()->getModuleNameByClassName($this);
}
/**
* Retrieves module name from call stack objects
*
* @return string
* @throws RuntimeException if assertion is called in not from EcomDev_PHPUnit_Test_Case
*/
protected static function getModuleNameFromCallStack()
{
$backTrace = debug_backtrace(true);
foreach ($backTrace as $call) {
if (isset($call['object']) && $call['object'] instanceof EcomDev_PHPUnit_Test_Case) {
return $call['object']->getModuleName();
}
}
throw new RuntimeException('Unable to retrieve module name from call stack, because assertion is not called from EcomDev_PHPUnit_Test_Case based class method');
}
/**
* Retrieves annotation by its name from different sources (class, method)
*
......@@ -393,7 +424,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
}
$mockBuilder->setMethods($methods);
$mockBuilder->setConstructorArgs($arguments);
$mockBuilder->setConstructorArgs($constructorArguments);
$mockBuilder->setMockClassName($mockClassName);
if ($isAbstract) {
......@@ -592,4 +623,5 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
parent::tearDown();
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -50,6 +50,7 @@
<models>Model</models>
<helpers>Helper</helpers>
<blocks>Block</blocks>
<config>Config</config>
</groups>
<!-- Test suite that will be used for creation of each of the tests -->
<test_suite>EcomDev_PHPUnit_Test_Suite_Group</test_suite>
......
<?php
/**
* Constraint for testing the configuration values
*
*
*/
class EcomDev_PHPUnit_Constraint_Config extends PHPUnit_Framework_Constraint
{
/**
* Configuration instance
*
* @var Varien_Simplexml_Config
*/
protected $config = null;
/**
* Configuration constraint
*
* @var PHPUnit_Framework_Constraint
*/
protected $constraint = null;
/**
* Creates configuration constraint for config object
*
* @param Varien_Simplexml_Config $config
*/
public function __construct($constraint)
{
$this->config = $config;
if (!$constraint instanceof EcomDev_PHPUnit_Constraint_Config_Interface) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'EcomDev_PHPUnit_Constraint_Config_Interface'
);
}
$this->constraint = $constraint;
}
/**
*
* @param mixed $other
* @param string $description
* @param boolean $not
*/
public function fail($other, $description, $not)
{
$nodeValue = $this->getNodeValue($other);
return $this->constraint->fail($nodeValue, $description, $not);
}
/**
* Retrives a node value from configuration by child constraint path
*
*
* @param Varien_Simplexml_Config $other
*/
protected function getNodeValue($config)
{
$nodeValue = $config->getNode(
$this->constraint->getNodePath()
);
if ($nodeValue === false) {
throw new EcomDev_PHPUnit_Constraint_Exception(
sprintf('Invalid node path specified for evaluation %s', $this->constraint->getNodePath())
);
}
return $nodeValue;
}
/**
* Evalutes constraint that is passed in the parameter
*
* @param Varien_Simplexml_Config $config
* @see PHPUnit_Framework_Constraint::evaluate()
*/
public function evaluate($config)
{
$nodeValue = $this->getNodeValue($config);
return $this->constraint->evaluate($nodeValue);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString()
{
return $this->constraint->toString();
}
}
<?php
/**
* Abstract class for constraints based on configuration
*
*/
abstract class EcomDev_PHPUnit_Constraint_Config_Abstract
extends PHPUnit_Framework_Constraint
implements EcomDev_PHPUnit_Constraint_Config_Interface
{
/**
* List of valiadation rules for expected value
* It is an associative array with key as type and value
* as an array of rules.
*
* First item of the rule array is mandatory indicator,
* second is function name for checking the type,
* third one is the type that will be displayed in invalid argument expception
* each of them can be ommited or if it between other ones just by specifying null value
*
* @var array
*/
protected $_expectedValueValidation = array();
/**
* List of types that will use diff for displaying fail result
*
* @var array
*/
protected $_typesWithDiff = array();
/**
* Config node path defined in the constructor
*
* @var string
*/
protected $_nodePath = null;
/**
* Comparisment type defined in the constructor
*
* @var string
*/
protected $_type = null;
/**
* Expected value defined in the constructor
*
* @var mixed
*/
protected $_expectedValue = null;
/**
* Custom actual value
*
* @var mixed
*/
protected $_actualValue = null;
/**
* Flag for using of actual valu in failure description
*
* @var boolean
*/
protected $_useActualValue = false;
/**
* Constraint constructor
*
* @param string $nodePath
* @param string $type
* @param mixed $expectedValue
*/
public function __construct($nodePath, $type, $expectedValue = null)
{
if (empty($nodePath) || !is_string($nodePath)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string', $type);
}
$reflection = EcomDev_Utils_Reflection::getRelflection(get_class($this));
$types = array();
foreach ($reflection->getConstants() as $name => $constant) {
if (strpos($name, 'TYPE_') === 0) {
$types[] = $constant;
}
}
if (empty($type) || !is_string($type) || !in_array($type, $types)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string', $type);
}
if (isset($this->_expectedValueValidation[$type])) {
$expectedValueType = (isset($this->_expectedValueValidation[$type][2]) ?
isset($this->_expectedValueValidation[$type][2]) :
'');
// Mandatory check
if (isset($this->_expectedValueValidation[$type][0])
&& $this->_expectedValueValidation[$type][0]
&& $expectedValue === null) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(3, $expectedValueType, $expectedValue);
}
// Type check
if (isset($this->_expectedValueValidation[$type][1])
&& !$this->_expectedValueValidation[$type][1]($expectedValue)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(3, $expectedValueType, $expectedValue);
}
}
$this->_nodePath = $nodePath;
$this->_type = $type;
$this->_expectedValue = $expectedValue;
}
/**
* Set actual value that will be used in the fail message
*
* @param mixed $actual
* @return EcomDev_PHPUnit_Constraint_Config_Abstract
*/
protected function setActualValue($actual)
{
$this->_useActualValue = true;
$this->_actualValue = $actual;
return $this;
}
/**
* Returns node path for checking
*
* (non-PHPdoc)
* @see EcomDev_PHPUnit_Constraint_Config_Interface::getNodePath()
*/
public function getNodePath()
{
return $this->_nodePath;
}
/**
* Calls internal protected method by defined constraint type
* Also can be passed a single argument
*
* @param string $prefix
*/
protected function callProtectedByType($prefix, $argument = null)
{
$camelizedType = uc_words($this->_type, '');
$methodName = $prefix . $camelizedType;
return $this->$methodName($argument);
}
/**
* Evaluates value by type.
* (non-PHPdoc)
* @see PHPUnit_Framework_Constraint::evaluate()
*/
public function evaluate($other)
{
if ($other === false) {
// If node was not found, than evaluation fails
return false;
}
return $this->callProtectedByType('evaluate', $other);
}
/**
* Generates a failure exception based on exception type
*
* (non-PHPdoc)
* @see PHPUnit_Framework_Constraint::fail()
*/
public function fail($other, $description, $not = FALSE)
{
$failureDescription = $this->failureDescription($other, $description, $not);
if (in_array($this->_type, $this->_typesWithDiff)) {
if ($this->_useActualValue) {
$other = $this->_actualValue;
} elseif ($other->hasChildren()) {
$other = $other->asNiceXml();
} else {
$other = (string) $other;
}
if ($this->_expectedValue instanceof Varien_Simplexml_Element) {
$expected = $this->_expectedValue->asNiceXml();
} else {
$expected = $this->_expectedValue;
}
throw new EcomDev_PHPUnit_Constraint_Exception(
$failureDescription,
PHPUnit_Util_Diff::diff($expected, $other),
$description
);
} else {
throw new EcomDev_PHPUnit_Constraint_Exception(
$failureDescription, $other->asNiceXml(), $description
);
}
}
/**
* Text reperesentation of constraint
* (non-PHPdoc)
* @see PHPUnit_Framework_SelfDescribing::toString()
*/
public function toString()
{
return $this->callProtectedByType('text');
}
}
\ No newline at end of file
<?php
/**
* Interface for configuration constraints
*
*/
interface EcomDev_PHPUnit_Constraint_Config_Interface
{
public function getNodePath();
}
\ No newline at end of file
<?php
class EcomDev_PHPUnit_Constraint_Config_Module extends EcomDev_PHPUnit_Constraint_Config_Abstract
{
const XML_PATH_MODULE_NODE = 'modules/%s';
const TYPE_IS_ACTIVE = 'is_active';
const TYPE_CODE_POOL = 'code_pool';
const TYPE_DEPENDS = 'depends';
const TYPE_EQUALS_VERSION = 'version';
const TYPE_LESS_THAN_VERSION = 'version_less_than';
const TYPE_GREATER_THAN_VERSION = 'version_greater_than';
/**
* Name of the module for constraint
*
* @var string
*/
protected $_moduleName = null;
/**
* Contraint for evaluation of config node
*
* @param string $nodePath
* @param string $type
* @param mixed $expectedValue
*/
public function __construct($moduleName, $type, $expectedValue)
{
$this->_expectedValueValidation += array(
self::TYPE_CODE_POOL => array(true, 'is_string', 'string'),
self::TYPE_DEPENDS => array(true, 'is_string', 'string'),
self::TYPE_EQUALS_VERSION => array(true, 'is_string', 'string'),
self::TYPE_LESS_THAN_VERSION => array(true, 'is_string', 'string'),
self::TYPE_GREATER_THAN_VERSION => array(true, 'is_string', 'string'),
);
$this->_typesWithDiff[] = self::TYPE_CODE_POOL;
$this->_typesWithDiff[] = self::TYPE_EQUALS_VERSION;
$this->_typesWithDiff[] = self::TYPE_LESS_THAN_VERSION;
$this->_typesWithDiff[] = self::TYPE_GREATER_THAN_VERSION;
parent::__construct(
sprintf(self::XML_PATH_MODULE_NODE, $moduleName),
$type,
$expectedValue
);
$this->_moduleName = $moduleName;
}
/**
* Evaluates module is active
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateIsActive($other)
{
return $other->is('active');
}
/**
* Text representation of module is active constraint
*
* @return string
*/
protected function textIsActive()
{
return 'is active';
}
/**
* Evaluates module code pool
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateCodePool($other)
{
$this->setActualValue((string)$other->codePool);
return $this->_actualValue === $this->_expectedValue;
}
/**
* Text representation of module is active constraint
*
* @return string
*/
protected function textCodePool()
{
return sprintf('is placed in %s code pool', $this->_expectedValue);
}
/**
* Evaluates module is dependent on expected one
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateDepends($other)
{
if (!isset($other->depends) || !$other->depends->hasChildren()) {
return false;
}
return isset($other->depends->{$this->_expectedValue});
}
/**
* Text representation of module dependance
*
* @return string
*/
protected function textDepends()
{
return sprintf('is dependent on %s module', $this->_expectedValue);
}
/**
* Evaluates module version is equal to expected
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateVersion($other)
{
return $this->compareVersion($other, '=');
}
/**
* Text representation of module version check
*
* @return string
*/
protected function textVersion()
{
return sprintf('version is equal to %s', $this->_expectedValue);
}
/**
* Evaluates module version is less than expected
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateVersionLessThan($other)
{
return $this->compareVersion($other, '<');
}
/**
* Text representation of module version check
*
* @return string
*/
protected function textVersionLessThan()
{
return sprintf('version is less than %s', $this->_expectedValue);
}
/**
* Evaluates module version is greater than expected
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateVersionGreaterThan($other)
{
return $this->compareVersion($other, '>');
}
/**
* Text representation of module version check
*
* @return string
*/
protected function textVersionGreaterThan()
{
return sprintf('version is greater than %s', $this->_expectedValue);
}
/**
* Internal comparisment of the module version
*
* @param Varien_Simplexml_Element $other
* @param string $operator
*/
protected function compareVersion($other, $operator)
{
$this->setActualValue((string)$other->version);
return version_compare($this->_actualValue, $this->_expectedValue, $operator);
}
/**
* 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 %s module %s.', $this->_moduleName, $this->toString()
);
}
}
<?php
class EcomDev_PHPUnit_Constraint_Config_Node
extends EcomDev_PHPUnit_Constraint_Config_Abstract
{
const TYPE_EQUALS_STRING = 'equals_string';
const TYPE_EQUALS_BOOLEAN = 'equals_boolean';
const TYPE_EQUALS_XML = 'equals_xml';
const TYPE_EQUALS_NUMBER = 'equals_decimal';
const TYPE_LESS_THAN = 'less_than';
const TYPE_GREATER_THAN = 'greater_than';
const TYPE_CONTAIN_VALUE = 'contain_values';
const TYPE_HAS_CHILD = 'has_child';
const TYPE_HAS_CHILDREN = 'has_children';
/**
* Contraint for evaluation of config node
*
* @param string $moduleName
* @param string $type
* @param mixed $expectedValue
*/
public function __construct($nodePath, $type, $expectedValue = null)
{
$this->_expectedValueValidation += array(
self::TYPE_EQUALS_STRING => array(true, 'is_string', 'string'),
self::TYPE_EQUALS_NUMBER => array(true, 'is_numeric', 'numeric'),
self::TYPE_LESS_THAN => array(true, 'is_numeric', 'numeric'),
self::TYPE_GREATER_THAN => array(true, 'is_numeric', 'numeric'),
self::TYPE_CONTAIN_VALUE => array(true, 'is_scalar', 'scalar'),
self::TYPE_HAS_CHILD => array(true, 'is_string', 'string')
);
$this->_typesWithDiff[] = self::TYPE_EQUALS_STRING;
$this->_typesWithDiff[] = self::TYPE_EQUALS_BOOLEAN;
$this->_typesWithDiff[] = self::TYPE_EQUALS_XML;
$this->_typesWithDiff[] = self::TYPE_EQUALS_NUMBER;
$this->_typesWithDiff[] = self::TYPE_LESS_THAN;
$this->_typesWithDiff[] = self::TYPE_GREATER_THAN;
parent::__construct($nodePath, $type, $expectedValue);
}
/**
* Check that node value is equal to string
*
* @param Varien_Simplexml_Element $other
*/
protected function evaluateEqualsString($other)
{
return (string)$other === $this->_expectedValue;
}
/**
* Text representation of the assertion
*
* @return string
*/
protected function textEqualsString()
{
return 'is equal to expected string';
}
/**
* Check that node value is equal to number
*
* @param Varien_Simplexml_Element $other
*/
protected function evaluateEqualsNumber($other)
{
return (float)$other == $this->_expectedValue;
}
/**
* Text representation of the assertion
*
* @return string
*/
protected function textEqualsNumber()
{
return 'is equal to expected number';
}
/**
* Check that node value is a string with such properties
*
* @param Varien_Simplexml_Element $other
*/
protected function evaluateLessThan($other)
{
return (float)$other > (float)$this->_expectedValue;
}
/**
* Text representation of the assertion
*
* @return string
*/
protected function textLessThan()
{
return sprintf('is less than %s', (float)$this->_expectedValue);
}
/**
* Check that node value is a string with such properties
*
* @param Varien_Simplexml_Element $other
*/
protected function evaluateGreaterThan($other)
{
return (float)$other > (float)$this->_expectedValue;
}
/**
* Text representation of the assertion
*
* @return string
*/
protected function textGreaterThan()
{
return sprintf('is greater than %s', (float)$this->_expectedValue);
}
/**
* Checks that string is not false value of a config flag
*
* @param Varien_Simplexml_Element $other
*/
protected function evaluateEqualsBoolean($other)
{
$other = (string) $other;
return !empty($other) && $other !== 'false';
}
/**
* Returns text reperesentation of flag checking
*
* @return string
*/
protected function textEqualsBoolean()
{
return 'is equals to boolean flag true';
}
/**
* Checks expected xml value with current configuration
*
* @param Varien_Simplexml_Element $other
* @throws RuntimeException if expected value is a valid xml object
*/
protected function evaluateEqualsXml($other)
{
// Normalize expected XML for matching appropriate xml structure without
// whitespaces, etc
if (!$this->_expectedValue instanceof Varien_Simplexml_Element) {
try {
if ($other instanceof SimpleXMLElement) {
$other = $other->asXML();
}
$expectedXml = new Varien_Simplexml_Element($this->_expectedValue);
} catch (Exception $e) {
throw new RuntimeException(sprintf(
'Expected value is not an xml string for node %s, passed expected value: %s, parsing error: %s',
$this->_nodePath,
PHPUnit_Util_Type::toString($this->_expectedValue),
$e->getMessage()
));
}
$this->_expectedValue = $expectedXml;
}
return $this->_expectedValue->asNiceXml() == $other->asNiceXml();
}
/**
* Returns text representatation of xml comparisment
*
* @return string
*/
protected function textEqualsXml()
{
return 'is the same as expected XML value';
}
/**
* Checks existance of a child with the expected value as the name
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateHasChild($other)
{
if (!$other->hasChildren()) {
return false;
}
if (!isset($other->{$this->_expectedValue})) {
return false;
}
return true;
}
/**
* Returns text represetnation of contain child assert
*
* @return string
*/
protected function textHasChild()
{
return sprintf('has "%s" child node', $this->_expectedValue);
}
/**
* Checks that configuration node has children
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateHasChildren($other)
{
return $other->hasChildren();
}
/**
* Returns text representation of has children assert
*
* @return string
*/
protected function textHasChildren()
{
return 'has children';
}
/**
* Checks multiple values nodes.
* Values are comma separated string
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateContainValue($other)
{
if ($other->hasChildren()) {
throw new RuntimeException(sprintf(
'Config node "%s" is not a string of comma separated values, passed expected value: %s',
$this->_nodePath,
PHPUnit_Util_Type::toString($this->_expectedValue)
));
}
$values = explode(',', (string)$other);
if (!in_array($this->_expectedValue, $values)) {
return true;
}
return false;
}
/**
* Returns text representation of contain value assert
*
* @return string
*/
protected function textContainValue()
{
return sprintf('contains "%s" in comma separated value list',
PHPUnit_Util_Type::toString($this->_expectedValue));
}
/**
* 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 configuration node "%s" %s.', $this->_nodePath, $this->toString()
);
}
}
<?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>
*/
/**
* Exception for failed constraints execution
*
*
*/
class EcomDev_PHPUnit_Constraint_Exception extends PHPUnit_Framework_ExpectationFailedException
{
protected $diff = null;
public function __construct($description, $diff = '', $message = '')
{
$this->diff = $diff;
parent::__construct($description, null, $message);
}
public function toString()
{
$result = parent::toString();
if (!empty($this->diff)) {
$result .= "\n" . $this->diff;
}
return $result;
}
}
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