Commit 358b1a68 authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

! Refactored test runners, fixture loaders, yaml file path resolvers

parent 0f3ea314
<?php
/* @depracated since 0.3.0 */
require_once 'app/code/community/EcomDev/PHPUnit/Test/bootstrap.php';
class UnitTests extends EcomDev_PHPUnit_Test_Suite
{
}
...@@ -131,6 +131,7 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App ...@@ -131,6 +131,7 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
* List of module names stored by class name * List of module names stored by class name
* *
* @var array * @var array
* @deprecated since 0.3.0
*/ */
protected $_moduleNameByClassName = array(); protected $_moduleNameByClassName = array();
...@@ -402,7 +403,7 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App ...@@ -402,7 +403,7 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
{ {
$className = (string)$this->getConfig()->getNode($configPath); $className = (string)$this->getConfig()->getNode($configPath);
$reflection = EcomDev_Utils_Reflection::getRelflection($className); $reflection = EcomDev_Utils_Reflection::getReflection($className);
if ($interface !== null && !$reflection->implementsInterface($interface)) { if ($interface !== null && !$reflection->implementsInterface($interface)) {
throw new RuntimeException( throw new RuntimeException(
sprintf('Invalid class name defined in configuration path %s, because %s does not implement %s interface', sprintf('Invalid class name defined in configuration path %s, because %s does not implement %s interface',
...@@ -443,31 +444,11 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App ...@@ -443,31 +444,11 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
* @param string|object $className * @param string|object $className
* @throws RuntimeException if module name was not found for the passed class name * @throws RuntimeException if module name was not found for the passed class name
* @return string * @return string
* @deprecated since 0.3.0
*/ */
public function getModuleNameByClassName($className) public function getModuleNameByClassName($className)
{ {
if (is_object($className)) { return EcomDev_PHPUnit_Test_Case_Util::getModuleNameByClassName($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];
} }
/** /**
...@@ -478,10 +459,11 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App ...@@ -478,10 +459,11 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
* @param string $className * @param string $className
* @param string $moduleName * @param string $moduleName
* @return EcomDev_PHPUnit_Model_App * @return EcomDev_PHPUnit_Model_App
* @deprecated since 0.3.0
*/ */
public function setModuleNameForClassName($className, $moduleName) public function setModuleNameForClassName($className, $moduleName)
{ {
$this->_moduleNameByClassName[$className] = $moduleName; EcomDev_PHPUnit_Test_Case_Util::setModuleNameForClassName($className, $moduleName);
return $this; return $this;
} }
......
<?php <?php
// Loading Spyc yaml parser,
// becuase Symfony component is not working propertly with nested
require_once 'Spyc/spyc.php';
class EcomDev_PHPUnit_Model_Expectation class EcomDev_PHPUnit_Model_Expectation
implements EcomDev_PHPUnit_Model_Expectation_Interface implements EcomDev_PHPUnit_Model_Expectation_Interface
{ {
...@@ -124,20 +120,25 @@ class EcomDev_PHPUnit_Model_Expectation ...@@ -124,20 +120,25 @@ class EcomDev_PHPUnit_Model_Expectation
*/ */
public function loadByTestCase(PHPUnit_Framework_TestCase $testCase) public function loadByTestCase(PHPUnit_Framework_TestCase $testCase)
{ {
$expectations = $testCase->getAnnotationByName('loadExpectation'); $expectations = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
get_class($testCase), 'loadExpectation', array('class', 'method'), $testCase->getName(false)
);
if (!$expectations) { if (!$expectations) {
$expectations[] = null; $expectations[] = $testCase->getName(false);
} }
$expectationData = array(); $expectationData = array();
foreach ($expectations as $expectation) { foreach ($expectations as $expectation) {
if (empty($expectation)) { if (empty($expectation)) {
$expectation = null; $expectation = $testCase->getName(false);
} }
$expectationFile = $testCase->getYamlFilePath('expectations', $expectation); $expectationFile = EcomDev_PHPUnit_Test_Case_Util::getYamlLoader(get_class($testCase))
->resolveFilePath(
get_class($testCase), EcomDev_PHPUnit_Model_Yaml_Loader::TYPE_EXPECTATION, $expectation
);
if (!$expectationFile) { if (!$expectationFile) {
$text = 'There was no expectation defined for current test case'; $text = 'There was no expectation defined for current test case';
...@@ -148,7 +149,7 @@ class EcomDev_PHPUnit_Model_Expectation ...@@ -148,7 +149,7 @@ class EcomDev_PHPUnit_Model_Expectation
} }
$expectationData = array_merge_recursive( $expectationData = array_merge_recursive(
$expectationData, Spyc::YAMLLoad($expectationFile) $expectationData, EcomDev_PHPUnit_Test_Case_Util::getYamlLoader()->load($expectationFile)
); );
} }
......
...@@ -16,9 +16,6 @@ ...@@ -16,9 +16,6 @@
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org> * @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/ */
// Loading Spyc yaml parser,
// because Symfony component is not working properly with nested structures
require_once 'Spyc/spyc.php';
/** /**
* Fixture model for Magento unit tests * Fixture model for Magento unit tests
...@@ -27,35 +24,45 @@ require_once 'Spyc/spyc.php'; ...@@ -27,35 +24,45 @@ require_once 'Spyc/spyc.php';
* *
*/ */
class EcomDev_PHPUnit_Model_Fixture class EcomDev_PHPUnit_Model_Fixture
extends Mage_Core_Model_Abstract extends Varien_Object
implements EcomDev_PHPUnit_Model_Fixture_Interface implements EcomDev_PHPUnit_Model_Fixture_Interface
{ {
// Configuration path for eav loaders // Configuration path for eav loaders
const XML_PATH_FIXTURE_EAV_LOADERS = 'phpunit/suite/fixture/eav'; /* @deprecated since 0.3.0 */
const XML_PATH_FIXTURE_EAV_LOADERS = EcomDev_PHPUnit_Model_Fixture_Processor_Eav::XML_PATH_FIXTURE_EAV_LOADERS;
// Processors configuration path
const XML_PATH_FIXTURE_PROCESSORS = 'phpunit/suite/fixture/processors';
// Default eav loader class node in loaders configuration // Default eav loader class node in loaders configuration
const DEFAULT_EAV_LOADER_NODE = 'default'; /* @deprecated since 0.3.0 */
const DEFAULT_EAV_LOADER_NODE = EcomDev_PHPUnit_Model_Fixture_Processor_Eav::DEFAULT_EAV_LOADER_NODE;
// Default shared fixture name // Default shared fixture name
const DEFAULT_SHARED_FIXTURE_NAME = 'default'; const DEFAULT_SHARED_FIXTURE_NAME = 'default';
// Default eav loader class alias // Default eav loader class alias
const DEFAULT_EAV_LOADER_CLASS = 'ecomdev_phpunit/fixture_eav_default'; /* @deprecated since 0.3.0 */
const DEFAULT_EAV_LOADER_CLASS = EcomDev_PHPUnit_Model_Fixture_Processor_Eav::DEFAULT_EAV_LOADER_CLASS;
// Key for storing fixture data into storage // Key for storing fixture data into storage
const STORAGE_KEY_FIXTURE = 'fixture'; const STORAGE_KEY_FIXTURE = 'fixture';
// Key for loaded tables into database // Key for loaded tables into database
const STORAGE_KEY_TABLES = 'tables'; /* @deprecated since 0.3.0 */
const STORAGE_KEY_TABLES = EcomDev_PHPUnit_Model_Fixture_Processor_Tables::STORAGE_KEY;
// Key for loaded entities by EAV loaders // Key for loaded entities by EAV loaders
const STORAGE_KEY_ENTITIES = 'entities'; /* @deprecated since 0.3.0 */
const STORAGE_KEY_ENTITIES = EcomDev_PHPUnit_Model_Fixture_Processor_Eav::STORAGE_KEY;
// Key for loaded cache options // Key for loaded cache options
const STORAGE_KEY_CACHE_OPTIONS = 'cache_options'; /* @deprecated since 0.3.0 */
const STORAGE_KEY_CACHE_OPTIONS = EcomDev_PHPUnit_Model_Fixture_Processor_Cache::STORAGE_KEY;
// Key for created scope models // Key for created scope models
const STORAGE_KEY_SCOPE = 'scope'; /* @deprecated since 0.3.0 */
const STORAGE_KEY_SCOPE = EcomDev_PHPUnit_Model_Fixture_Processor_Scope::STORAGE_KEY;
/** /**
* Fixtures array, contains config, * Fixtures array, contains config,
...@@ -111,22 +118,19 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -111,22 +118,19 @@ class EcomDev_PHPUnit_Model_Fixture
protected $_options = array(); protected $_options = array();
/** /**
* vfsStream wrapper instance * Processors list
* *
* @var EcomDev_PHPUnit_Model_Fixture_Vfs * @var EcomDev_PHPUnit_Model_Fixture_Processor_Interface[]
*/ */
protected $_vfs = null; protected $_processors = array();
/** /**
* List of scope model aliases by scope type * List of scope model aliases by scope type
* *
* @var array * @var array
* @deprecated since 0.3.0
*/ */
protected static $_scopeModelByType = array( protected static $_scopeModelByType = array();
'store' => 'core/store',
'group' => 'core/store_group',
'website' => 'core/website'
);
/** /**
* Associative array of configuration nodes xml that was changed by fixture, * Associative array of configuration nodes xml that was changed by fixture,
...@@ -153,7 +157,6 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -153,7 +157,6 @@ class EcomDev_PHPUnit_Model_Fixture
*/ */
protected function _construct() protected function _construct()
{ {
$this->_init('ecomdev_phpunit/fixture');
// Additional property for test data fixture // Additional property for test data fixture
$this->setTestData(new Varien_Object()); $this->setTestData(new Varien_Object());
} }
...@@ -170,6 +173,16 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -170,6 +173,16 @@ class EcomDev_PHPUnit_Model_Fixture
return $this; return $this;
} }
/**
* Retrieve fixture options
*
* @return array
*/
public function getOptions()
{
return $this->_options;
}
/** /**
* Sets storage for fixtures * Sets storage for fixtures
* *
...@@ -275,6 +288,16 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -275,6 +288,16 @@ class EcomDev_PHPUnit_Model_Fixture
return $this->getScope() === self::SCOPE_LOCAL; return $this->getScope() === self::SCOPE_LOCAL;
} }
/**
* Check that current fixture scope is equal to SCOPE_LOCAL
*
* @return boolean
*/
public function isScopeDefault()
{
return $this->getScope() === self::SCOPE_DEFAULT;
}
/** /**
* Loads fixture files from test case annotations * Loads fixture files from test case annotations
* *
...@@ -283,12 +306,6 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -283,12 +306,6 @@ class EcomDev_PHPUnit_Model_Fixture
*/ */
public function loadByTestCase(PHPUnit_Framework_TestCase $testCase) public function loadByTestCase(PHPUnit_Framework_TestCase $testCase)
{ {
$cacheOptions = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
get_class($testCase), 'cache', 'method', $testCase->getName(false)
);
$this->_parseCacheOptions($cacheOptions);
$fixtures = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass( $fixtures = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
get_class($testCase), 'loadFixture', array('class', 'method'), $testCase->getName(false) get_class($testCase), 'loadFixture', array('class', 'method'), $testCase->getName(false)
); );
...@@ -305,12 +322,6 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -305,12 +322,6 @@ class EcomDev_PHPUnit_Model_Fixture
*/ */
public function loadForClass($className) public function loadForClass($className)
{ {
$cacheOptions = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
$className, 'cache', 'class'
);
$this->_parseCacheOptions($cacheOptions);
$fixtures = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass( $fixtures = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
$className, 'loadSharedFixture', 'class' $className, 'loadSharedFixture', 'class'
); );
...@@ -324,26 +335,25 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -324,26 +335,25 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $annotations * @param array $annotations
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _parseCacheOptions($annotations) protected function _parseCacheOptions($annotations)
{ {
$cacheOptions = array(); return $this;
foreach ($annotations as $annotation) {
list($action, $cacheType) = preg_split('/\s+/', trim($annotation));
$flag = ($action === 'off' ? 0 : 1);
if ($cacheType === 'all') {
foreach (Mage::app()->getCacheInstance()->getTypes() as $type) {
$cacheOptions[$type->getId()] = $flag;
}
} else {
$cacheOptions[$cacheType] = $flag;
}
} }
if ($cacheOptions) { /**
$this->_fixture['cache_options'] = $cacheOptions; * Sets fixture value
} *
* @param string $key
* @param array[] $value
*
* @return EcomDev_PHPUnit_Model_Fixture
*/
public function setFixtureValue($key, $value)
{
$this->_fixture[$key] = $value;
return $this;
} }
/** /**
...@@ -351,6 +361,8 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -351,6 +361,8 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $fixtures * @param array $fixtures
* @param string|EcomDev_PHPUnit_Test_Case $classOrInstance * @param string|EcomDev_PHPUnit_Test_Case $classOrInstance
*
* @throws RuntimeException
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
*/ */
protected function _loadFixtureFiles(array $fixtures, $classOrInstance) protected function _loadFixtureFiles(array $fixtures, $classOrInstance)
...@@ -364,7 +376,8 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -364,7 +376,8 @@ class EcomDev_PHPUnit_Model_Fixture
} }
$className = (is_string($classOrInstance) ? $classOrInstance : get_class($classOrInstance)); $className = (is_string($classOrInstance) ? $classOrInstance : get_class($classOrInstance));
$filePath = EcomDev_PHPUnit_Test_Case_Util::getYamlFilePath($className, 'fixtures', $fixture); $filePath = EcomDev_PHPUnit_Test_Case_Util::getYamlLoader()
->resolveFilePath($className, EcomDev_PHPUnit_Model_Yaml_Loader::TYPE_FIXTURE, $fixture);
if (!$filePath) { if (!$filePath) {
throw new RuntimeException('Unable to load fixture for test'); throw new RuntimeException('Unable to load fixture for test');
...@@ -385,7 +398,7 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -385,7 +398,7 @@ class EcomDev_PHPUnit_Model_Fixture
*/ */
public function loadYaml($filePath) public function loadYaml($filePath)
{ {
$data = Spyc::YAMLLoad($filePath); $data = EcomDev_PHPUnit_Test_Case_Util::getYamlLoader()->load($filePath);
if (empty($this->_fixture)) { if (empty($this->_fixture)) {
$this->_fixture = $data; $this->_fixture = $data;
...@@ -396,6 +409,26 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -396,6 +409,26 @@ class EcomDev_PHPUnit_Model_Fixture
return $this; return $this;
} }
/**
* Returns list of available processors for fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Interface[]
*/
public function getProcessors()
{
if (empty($this->_processors)) {
$processorsNode = Mage::getConfig()->getNode(self::XML_PATH_FIXTURE_PROCESSORS);
foreach ($processorsNode->children() as $code => $processorAlias) {
$processor = Mage::getSingleton((string)$processorAlias);
if ($processor instanceof EcomDev_PHPUnit_Model_Fixture_Processor_Interface) {
$this->_processors[$code] = $processor;
}
}
}
return $this->_processors;
}
/** /**
* Applies loaded fixture * Applies loaded fixture
* *
...@@ -403,13 +436,17 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -403,13 +436,17 @@ class EcomDev_PHPUnit_Model_Fixture
*/ */
public function apply() public function apply()
{ {
$processors = $this->getProcessors();
// Initialize fixture processors
foreach ($processors as $processor) {
$processor->initialize($this);
}
$this->setStorageData(self::STORAGE_KEY_FIXTURE, $this->_fixture); $this->setStorageData(self::STORAGE_KEY_FIXTURE, $this->_fixture);
$reflection = EcomDev_Utils_Reflection::getRelflection($this);
foreach ($this->_fixture as $part => $data) { foreach ($this->_fixture as $part => $data) {
$method = '_apply' . uc_words($part, '', '_'); if (isset($processors[$part])) {
if ($reflection->hasMethod($method)) { $processors[$part]->apply($data, $part, $this);
$this->$method($data);
} }
} }
...@@ -433,11 +470,11 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -433,11 +470,11 @@ class EcomDev_PHPUnit_Model_Fixture
$this->_fixture = $fixture; $this->_fixture = $fixture;
$this->setStorageData(self::STORAGE_KEY_FIXTURE, null); $this->setStorageData(self::STORAGE_KEY_FIXTURE, null);
$reflection = EcomDev_Utils_Reflection::getRelflection($this);
$processors = $this->getProcessors();
foreach ($this->_fixture as $part => $data) { foreach ($this->_fixture as $part => $data) {
$method = '_discard' . uc_words($part, '', '_'); if (isset($processors[$part])) {
if ($reflection->hasMethod($method)) { $processors[$part]->discard($data, $part, $this);
$this->$method($data);
} }
} }
...@@ -449,15 +486,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -449,15 +486,10 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $options * @param array $options
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _applyCacheOptions($options) protected function _applyCacheOptions($options)
{ {
$originalOptions = Mage::app()->getCacheOptions();
$this->setStorageData(self::STORAGE_KEY_CACHE_OPTIONS, $originalOptions);
$options += $originalOptions;
Mage::app()->setCacheOptions($options);
return $this; return $this;
} }
...@@ -465,12 +497,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -465,12 +497,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Discards changes that were made to Magento cache * Discards changes that were made to Magento cache
* *
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _discardCacheOptions() protected function _discardCacheOptions()
{ {
Mage::app()->setCacheOptions(
$this->getStorageData(self::STORAGE_KEY_CACHE_OPTIONS)
);
return $this; return $this;
} }
...@@ -479,32 +509,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -479,32 +509,10 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $configuration * @param array $configuration
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _applyConfig($configuration) protected function _applyConfig($configuration)
{ {
if (!is_array($configuration)) {
throw new InvalidArgumentException('Configuration part should be an associative list');
}
Mage::getConfig()->loadScopeSnapshot();
foreach ($configuration as $path => $value) {
$this->_setConfigNodeValue($path, $value);
}
Mage::getConfig()->loadDb();
// Flush website and store configuration caches
foreach (Mage::app()->getWebsites(true) as $website) {
EcomDev_Utils_Reflection::setRestrictedPropertyValue(
$website, '_configCache', array()
);
}
foreach (Mage::app()->getStores(true) as $store) {
EcomDev_Utils_Reflection::setRestrictedPropertyValue(
$store, '_configCache', array()
);
}
return $this; return $this;
} }
...@@ -513,32 +521,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -513,32 +521,10 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $configuration * @param array $configuration
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _applyConfigXml($configuration) protected function _applyConfigXml($configuration)
{ {
if (!is_array($configuration)) {
throw new InvalidArgumentException('Configuration part should be an associative list');
}
foreach ($configuration as $path => $value) {
if (!is_string($value)) {
throw new InvalidArgumentException('Configuration value should be a valid xml string');
}
try {
$xmlElement = new Varien_Simplexml_Element($value);
} catch (Exception $e) {
throw new InvalidArgumentException('Configuration value should be a valid xml string', 0, $e);
}
$node = Mage::getConfig()->getNode($path);
if (!$node) {
throw new InvalidArgumentException('Configuration value should be a valid xml string');
}
$node->extend($xmlElement, true);
}
return $this; return $this;
} }
...@@ -546,11 +532,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -546,11 +532,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Restores config to a previous configuration scope * Restores config to a previous configuration scope
* *
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _restoreConfig() protected function _restoreConfig()
{ {
Mage::getConfig()->loadScopeSnapshot();
Mage::getConfig()->loadDb();
return $this; return $this;
} }
...@@ -558,10 +543,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -558,10 +543,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Reverts fixture configuration values in Mage_Core_Model_Config * Reverts fixture configuration values in Mage_Core_Model_Config
* *
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _discardConfig() protected function _discardConfig()
{ {
$this->_restoreConfig();
return $this; return $this;
} }
...@@ -569,12 +554,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -569,12 +554,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Reverts fixture configuration xml values in Mage_Core_Model_Config * Reverts fixture configuration xml values in Mage_Core_Model_Config
* *
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _discardConfigXml() protected function _discardConfigXml()
{ {
if (!isset($this->_fixture['config'])) {
$this->_restoreConfig();
}
return $this; return $this;
} }
...@@ -583,34 +566,11 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -583,34 +566,11 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $tables * @param array $tables
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _applyTables($tables) protected function _applyTables($tables)
{ {
if (!is_array($tables)) { return $this;
throw new InvalidArgumentException(
'Tables part should be an associative list with keys as table entity and values as list of associative rows'
);
}
$ignoreCleanUp = array();
// Ignore cleaning of tables if shared fixture loaded something
if ($this->isScopeLocal() && $this->getStorageData(self::STORAGE_KEY_TABLES, self::SCOPE_SHARED)) {
$ignoreCleanUp = array_keys($this->getStorageData(self::STORAGE_KEY_TABLES, self::SCOPE_SHARED));
}
$this->getResource()->beginTransaction();
foreach ($tables as $tableEntity => $data) {
if (!in_array($tableEntity, $ignoreCleanUp)) {
$this->getResource()->cleanTable($tableEntity);
}
if (!empty($data)) {
$this->getResource()->loadTableData($tableEntity, $data);
}
}
$this->getResource()->commit();
$this->setStorageData(self::STORAGE_KEY_TABLES, $tables);
} }
/** /**
...@@ -618,33 +578,11 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -618,33 +578,11 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $tables * @param array $tables
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _discardTables($tables) protected function _discardTables($tables)
{ {
if (!is_array($tables)) { return $this;
throw new InvalidArgumentException(
'Tables part should be an associative list with keys as table entity and values as list of associative rows'
);
}
$restoreTableData = array();
// Data for tables used in shared fixture
if ($this->isScopeLocal() && $this->getStorageData(self::STORAGE_KEY_TABLES, self::SCOPE_SHARED)) {
$restoreTableData = $this->getStorageData(self::STORAGE_KEY_TABLES, self::SCOPE_SHARED);
}
$this->getResource()->beginTransaction();
foreach (array_keys($tables) as $tableEntity) {
$this->getResource()->cleanTable($tableEntity);
if (isset($restoreTableData[$tableEntity])) {
$this->getResource()->loadTableData($tableEntity, $restoreTableData[$tableEntity]);
}
}
$this->getResource()->commit();
$this->setStorageData(self::STORAGE_KEY_TABLES, null);
} }
/** /**
...@@ -653,10 +591,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -653,10 +591,10 @@ class EcomDev_PHPUnit_Model_Fixture
* @param string $path * @param string $path
* @param string $value * @param string $value
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _setConfigNodeValue($path, $value) protected function _setConfigNodeValue($path, $value)
{ {
Mage::getConfig()->setNode($path, $value);
return $this; return $this;
} }
...@@ -665,20 +603,11 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -665,20 +603,11 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param string $entityType * @param string $entityType
* @return EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract * @return EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract
* @deprecated since 0.3.0
*/ */
protected function _getEavLoader($entityType) protected function _getEavLoader($entityType)
{ {
$loaders = Mage::getConfig()->getNode(self::XML_PATH_FIXTURE_EAV_LOADERS); return false;
if (isset($loaders->$entityType)) {
$classAlias = (string)$loaders->$entityType;
} elseif (isset($loaders->{self::DEFAULT_EAV_LOADER_NODE})) {
$classAlias = (string)$loaders->{self::DEFAULT_EAV_LOADER_NODE};
} else {
$classAlias = self::DEFAULT_EAV_LOADER_CLASS;
}
return Mage::getResourceSingleton($classAlias);
} }
/** /**
...@@ -686,26 +615,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -686,26 +615,10 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $entities * @param array $entities
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _applyEav($entities) protected function _applyEav($entities)
{ {
if (!is_array($entities)) {
throw new InvalidArgumentException('EAV part should be an associative list with rows as value and entity type as key');
}
$this->getResource()->beginTransaction();
foreach ($entities as $entityType => $values) {
$this->_getEavLoader($entityType)
->setFixture($this)
->setOptions($this->_options)
->loadEntity($entityType, $values);
}
$this->getResource()->commit();
$this->setStorageData(self::STORAGE_KEY_ENTITIES, array_keys($entities));
return $this; return $this;
} }
...@@ -714,27 +627,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -714,27 +627,10 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $entities * @param array $entities
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _discardEav($entities) protected function _discardEav($entities)
{ {
$ignoreCleanUp = array();
// Ignore cleaning of entities if shared fixture loaded something for them
if ($this->isScopeLocal() && $this->getStorageData(self::STORAGE_KEY_ENTITIES, self::SCOPE_SHARED)) {
$ignoreCleanUp = $this->getStorageData(self::STORAGE_KEY_ENTITIES, self::SCOPE_SHARED);
}
$this->getResource()->beginTransaction();
foreach (array_keys($entities) as $entityType) {
if (in_array($entityType, $ignoreCleanUp)) {
continue;
}
$this->_getEavLoader($entityType)
->cleanEntity($entityType);
}
$this->getResource()->commit();
return $this; return $this;
} }
...@@ -744,32 +640,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -744,32 +640,10 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $types * @param array $types
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _applyScope($types) protected function _applyScope($types)
{ {
Mage::app()->disableEvents();
// Validate received fixture data
$this->_validateScope($types);
if ($this->getStorageData(self::STORAGE_KEY_SCOPE) !== null) {
throw new RuntimeException('Scope data was not cleared after previous test');
}
$scopeModels = array();
foreach ($types as $type => $rows) {
foreach ($rows as $row) {
$model = $this->_handleScopeRow($type, $row);
if ($model) {
$scopeModels[$type][$model->getId()] = $model;
}
}
}
$this->setStorageData(self::STORAGE_KEY_SCOPE, $scopeModels);
Mage::app()->enableEvents();
Mage::app()->reinitStores();
return $this; return $this;
} }
...@@ -779,63 +653,22 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -779,63 +653,22 @@ class EcomDev_PHPUnit_Model_Fixture
* @param string $type * @param string $type
* @param array $row * @param array $row
* @return boolean|Mage_Core_Model_Abstract * @return boolean|Mage_Core_Model_Abstract
* @deprecated since 0.3.0
*/ */
protected function _handleScopeRow($type, $row) protected function _handleScopeRow($type, $row)
{ {
$previousScope = array();
if ($this->isScopeLocal() && $this->getStorageData(self::STORAGE_KEY_SCOPE, self::SCOPE_SHARED) !== null) {
$previousScope = $this->getStorageData(self::STORAGE_KEY_SCOPE, self::SCOPE_SHARED);
}
if (isset($previousScope[$type][$row[$type . '_id']])) {
return false; return false;
} }
$scopeModel = Mage::getModel(self::$_scopeModelByType[$type]);
$scopeModel->setData($row);
// Change property for saving new objects with specified ids
EcomDev_Utils_Reflection::setRestrictedPropertyValues(
$scopeModel->getResource(),
array(
'_isPkAutoIncrement' => false
)
);
$scopeModel->isObjectNew(true);
$scopeModel->save();
// Revert changed property
EcomDev_Utils_Reflection::setRestrictedPropertyValues(
$scopeModel->getResource(),
array(
'_isPkAutoIncrement' => true
)
);
return $scopeModel;
}
/** /**
* Validate scope data * Validate scope data
* *
* @param array $types * @param array $types
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _validateScope($types) protected function _validateScope($types)
{ {
foreach ($types as $type => $rows) {
if (!isset(self::$_scopeModelByType[$type])) {
throw new RuntimeException(sprintf('Unknown "%s" scope type specified', $type));
}
foreach ($rows as $rowNumber => $row) {
if (!isset($row[$type . '_id'])) {
throw new RuntimeException(sprintf('Missing primary key for "%s" scope entity at #%d row', $type, $rowNumber + 1));
}
}
}
return $this; return $this;
} }
...@@ -844,34 +677,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -844,34 +677,10 @@ class EcomDev_PHPUnit_Model_Fixture
* i.e., website, store, store group * i.e., website, store, store group
* *
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _discardScope() protected function _discardScope()
{ {
if ($this->getStorageData(self::STORAGE_KEY_SCOPE) === null) {
return $this;
}
Mage::app()->disableEvents();
$scope = array_reverse($this->getStorageData(self::STORAGE_KEY_SCOPE));
foreach ($scope as $models) {
foreach ($models as $model) {
$model->delete();
}
}
$this->setStorageData(self::STORAGE_KEY_SCOPE, null);
Mage::app()->getCache()->clean(
Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG,
array(
Mage_Core_Model_Store::CACHE_TAG,
Mage_Core_Model_Store_Group::CACHE_TAG,
Mage_Core_Model_Website::CACHE_TAG
)
);
Mage::app()->enableEvents();
Mage::app()->reinitStores();
return $this; return $this;
} }
...@@ -907,7 +716,7 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -907,7 +716,7 @@ class EcomDev_PHPUnit_Model_Fixture
*/ */
public function vfsAutoload($className) public function vfsAutoload($className)
{ {
if (strpos($className, 'org\\bovigo\\vfs') !== 0) { if (strpos($className, 'vfs') !== 0) {
return false; return false;
} }
...@@ -923,10 +732,10 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -923,10 +732,10 @@ class EcomDev_PHPUnit_Model_Fixture
* *
* @param array $data * @param array $data
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _applyVfs($data) protected function _applyVfs($data)
{ {
$this->getVfs()->apply($data, $this->isScopeLocal());
return $this; return $this;
} }
...@@ -934,6 +743,7 @@ class EcomDev_PHPUnit_Model_Fixture ...@@ -934,6 +743,7 @@ class EcomDev_PHPUnit_Model_Fixture
* Discards VFS structure fixture * Discards VFS structure fixture
* *
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected function _discardVfs() protected function _discardVfs()
{ {
......
...@@ -36,6 +36,13 @@ interface EcomDev_PHPUnit_Model_Fixture_Interface extends EcomDev_PHPUnit_Model_ ...@@ -36,6 +36,13 @@ interface EcomDev_PHPUnit_Model_Fixture_Interface extends EcomDev_PHPUnit_Model_
*/ */
public function setOptions(array $options); public function setOptions(array $options);
/**
* Sets fixture options
*
* @return array
*/
public function getOptions();
/** /**
* Sets storage for fixtures * Sets storage for fixtures
* *
...@@ -106,6 +113,16 @@ interface EcomDev_PHPUnit_Model_Fixture_Interface extends EcomDev_PHPUnit_Model_ ...@@ -106,6 +113,16 @@ interface EcomDev_PHPUnit_Model_Fixture_Interface extends EcomDev_PHPUnit_Model_
*/ */
public function loadForClass($className); public function loadForClass($className);
/**
* Sets fixture value
*
* @param string $key
* @param array[] $value
*
* @return EcomDev_PHPUnit_Model_Fixture_Interface
*/
public function setFixtureValue($key, $value);
/** /**
* Returns VFS wrapper instance * Returns VFS wrapper instance
* *
......
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Fixture_Processor_Cache implements EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
const STORAGE_KEY = 'cache_options';
/**
* Initializes cache options
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Cache
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$options = $fixture->getOptions();
if (isset($options['cache'])) {
$cacheOptions = array();
foreach ($options['cache'] as $annotation) {
list($action, $cacheType) = preg_split('/\s+/', trim($annotation));
$flag = ($action === 'off' ? 0 : 1);
if ($cacheType === 'all') {
foreach (Mage::app()->getCacheInstance()->getTypes() as $type) {
$cacheOptions[$type->getId()] = $flag;
}
} else {
$cacheOptions[$cacheType] = $flag;
}
}
$fixture->setFixtureValue('cache_options', $cacheOptions);
}
return $this;
}
/**
* Apply cache options from the fixture data
*
* @param array $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Cache
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$originalOptions = EcomDev_PHPUnit_Test_Case_Util::app()->getCacheOptions();
$fixture->setStorageData(self::STORAGE_KEY, $originalOptions);
$data += $originalOptions;
EcomDev_PHPUnit_Test_Case_Util::app()->setCacheOptions($data);
return $this;
}
/**
* Discard applied cache options
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Cache
*/
public function discard(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
EcomDev_PHPUnit_Test_Case_Util::app()->setCacheOptions(
$fixture->getStorageData(self::STORAGE_KEY)
);
return $this;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Fixture_Processor_Config implements EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
/**
* Does nothing
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Config
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
return $this;
}
/**
* Apply cache options from the fixture data
*
* @param array $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Config
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$key === 'config_xml' ? $this->_applyConfigXml($data) : $this->_applyConfig($data);
return $this;
}
/**
* Applies fixture configuration values into Mage_Core_Model_Config
*
* @param array $configuration
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Config
* @throws InvalidArgumentException
*/
protected function _applyConfig($configuration)
{
if (!is_array($configuration)) {
throw new InvalidArgumentException('Configuration part should be an associative list');
}
Mage::getConfig()->loadScopeSnapshot();
foreach ($configuration as $path => $value) {
$this->_setConfigNodeValue($path, $value);
}
Mage::getConfig()->loadDb();
// Flush website and store configuration caches
foreach (Mage::app()->getWebsites(true) as $website) {
EcomDev_Utils_Reflection::setRestrictedPropertyValue(
$website, '_configCache', array()
);
}
foreach (Mage::app()->getStores(true) as $store) {
EcomDev_Utils_Reflection::setRestrictedPropertyValue(
$store, '_configCache', array()
);
}
return $this;
}
/**
* Applies raw xml data to config node
*
* @param array $configuration
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Config
* @throws InvalidArgumentException
*/
protected function _applyConfigXml($configuration)
{
if (!is_array($configuration)) {
throw new InvalidArgumentException('Configuration part should be an associative list');
}
foreach ($configuration as $path => $value) {
if (!is_string($value)) {
throw new InvalidArgumentException('Configuration value should be a valid xml string');
}
try {
$xmlElement = new Varien_Simplexml_Element($value);
} catch (Exception $e) {
throw new InvalidArgumentException('Configuration value should be a valid xml string', 0, $e);
}
$node = Mage::getConfig()->getNode($path);
if (!$node) {
throw new InvalidArgumentException('Configuration value should be a valid xml string');
}
$node->extend($xmlElement, true);
}
return $this;
}
/**
* Discard applied cache options
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Config
*/
public function discard(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$this->_restoreConfig();
return $this;
}
/**
* Restores config to a previous configuration scope
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Config
*/
protected function _restoreConfig()
{
Mage::getConfig()->loadScopeSnapshot();
Mage::getConfig()->loadDb();
return $this;
}
/**
* Sets configuration value
*
* @param string $path
* @param string $value
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Config
*/
protected function _setConfigNodeValue($path, $value)
{
if (($originalNode = Mage::getConfig()->getNode($path)) && $originalNode->getAttribute('backend_model')) {
$backendModel = $originalNode->getAttribute('backend_model');
$backend = Mage::getModel((string) $backendModel);
$backend->setPath($path)->setValue($value);
EcomDev_Utils_Reflection::invokeRestrictedMethod($backend, '_beforeSave');
$value = $backend->getValue();
}
Mage::getConfig()->setNode($path, $value);
return $this;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Fixture_Processor_Eav
extends Mage_Core_Model_Abstract
implements EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
const STORAGE_KEY = 'entities';
// Configuration path for eav loaders
const XML_PATH_FIXTURE_EAV_LOADERS = 'phpunit/suite/fixture/eav';
// Default eav loader class node in loaders configuration
const DEFAULT_EAV_LOADER_NODE = 'default';
// Default eav loader class alias
const DEFAULT_EAV_LOADER_CLASS = 'ecomdev_phpunit/fixture_eav_default';
/**
* Initialize fixture resource model
*/
protected function _construct()
{
$this->_init('ecomdev_phpunit/fixture');
}
/**
* Does nothing
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Eav
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
return $this;
}
/**
* Retrieves eav loader for a particular entity type
*
* @param string $entityType
* @return EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract
*/
protected function _getEavLoader($entityType)
{
$loaders = Mage::getConfig()->getNode(self::XML_PATH_FIXTURE_EAV_LOADERS);
if (isset($loaders->$entityType)) {
$classAlias = (string)$loaders->$entityType;
} elseif (isset($loaders->{self::DEFAULT_EAV_LOADER_NODE})) {
$classAlias = (string)$loaders->{self::DEFAULT_EAV_LOADER_NODE};
} else {
$classAlias = self::DEFAULT_EAV_LOADER_CLASS;
}
return Mage::getResourceSingleton($classAlias);
}
/**
* Apply eav records from fixture file
*
* @param array $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Eav
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$this->getResource()->beginTransaction();
foreach ($data as $entityType => $values) {
$this->_getEavLoader($entityType)
->setFixture($fixture)
->setOptions($fixture->getOptions())
->loadEntity($entityType, $values);
}
$this->getResource()->commit();
$fixture->setStorageData(self::STORAGE_KEY, array_keys($data));
return $this;
}
/**
* Discard applied eav records
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Eav
*/
public function discard(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$ignoreCleanUp = array();
// Ignore cleaning of entities if shared fixture loaded something for them
if ($fixture->isScopeLocal()
&& $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)) {
$ignoreCleanUp = $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED);
}
$this->getResource()->beginTransaction();
foreach (array_keys($data) as $entityType) {
if (in_array($entityType, $ignoreCleanUp)) {
continue;
}
$this->_getEavLoader($entityType)
->cleanEntity($entityType);
}
$this->getResource()->commit();
return $this;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
interface EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
/**
* Applies data from fixture file
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Interface
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture);
/**
* Discards data from fixture file
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Interface
*/
public function discard(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture);
/**
* Initializes fixture processor before applying data
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Interface
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture);
}
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Fixture_Processor_Scope
implements EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
const STORAGE_KEY = 'scope';
/**
* Model aliases by type of scope
*
* @var array
*/
protected $modelByType = array(
'store' => 'core/store',
'group' => 'core/store_group',
'website' => 'core/website'
);
/**
* Does nothing
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Scope
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
return $this;
}
/**
* Handle scope row data
*
* @param string $type
* @param array $row
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return boolean|Mage_Core_Model_Abstract
*/
protected function _handleScopeRow($type, $row, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$previousScope = array();
if ($fixture->isScopeLocal()
&& $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED) !== null) {
$previousScope = $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED);
}
if (isset($previousScope[$type][$row[$type . '_id']])) {
return false;
}
$scopeModel = Mage::getModel($this->modelByType[$type]);
$scopeModel->setData($row);
// Change property for saving new objects with specified ids
EcomDev_Utils_Reflection::setRestrictedPropertyValues(
$scopeModel->getResource(),
array(
'_isPkAutoIncrement' => false
)
);
try {
$scopeModel->isObjectNew(true);
$scopeModel->save();
} catch (Exception $e) {
Mage::logException($e);
// Skip duplicated key violation, since it might be a problem
// of previous run with fatal error
// Revert changed property
EcomDev_Utils_Reflection::setRestrictedPropertyValues(
$scopeModel->getResource(),
array(
'_isPkAutoIncrement' => true
)
);
// Load to make possible deletion
$scopeModel->load($row[$type . '_id']);
}
// Revert changed property
EcomDev_Utils_Reflection::setRestrictedPropertyValues(
$scopeModel->getResource(),
array(
'_isPkAutoIncrement' => true
)
);
return $scopeModel;
}
/**
* Validate scope data
*
* @param array $types
* @throws RuntimeException
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Scope
*/
protected function _validateScope($types)
{
foreach ($types as $type => $rows) {
if (!isset($this->modelByType[$type])) {
throw new RuntimeException(sprintf('Unknown "%s" scope type specified', $type));
}
foreach ($rows as $rowNumber => $row) {
if (!isset($row[$type . '_id'])) {
throw new RuntimeException(sprintf('Missing primary key for "%s" scope entity at #%d row', $type, $rowNumber + 1));
}
}
}
return $this;
}
/**
* Apply scoped data (store, website, group)
*
* @param array $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @throws RuntimeException
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Scope
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
EcomDev_PHPUnit_Test_Case_Util::app()->disableEvents();
// Validate received fixture data
$this->_validateScope($data);
if ($fixture->getStorageData(self::STORAGE_KEY) !== null) {
throw new RuntimeException('Scope data was not cleared after previous test');
}
$scopeModels = array();
foreach ($data as $type => $rows) {
foreach ($rows as $row) {
$model = $this->_handleScopeRow($type, $row, $fixture);
if ($model) {
$scopeModels[$type][$model->getId()] = $model;
}
}
}
$fixture->setStorageData(self::STORAGE_KEY, $scopeModels);
EcomDev_PHPUnit_Test_Case_Util::app()->enableEvents();
EcomDev_PHPUnit_Test_Case_Util::app()->reinitStores();
return $this;
}
/**
* Discard applied scope models
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Scope
*/
public function discard(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
if ($fixture->getStorageData(self::STORAGE_KEY) === null) {
return $this;
}
EcomDev_PHPUnit_Test_Case_Util::app()->disableEvents();
$scope = array_reverse($fixture->getStorageData(self::STORAGE_KEY));
foreach ($scope as $models) {
foreach ($models as $model) {
$model->delete();
}
}
$fixture->setStorageData(self::STORAGE_KEY, null);
EcomDev_PHPUnit_Test_Case_Util::app()->getCache()->clean(
Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG,
array(
Mage_Core_Model_Store::CACHE_TAG,
Mage_Core_Model_Store_Group::CACHE_TAG,
Mage_Core_Model_Website::CACHE_TAG
)
);
EcomDev_PHPUnit_Test_Case_Util::app()->enableEvents();
EcomDev_PHPUnit_Test_Case_Util::app()->reinitStores();
return $this;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Fixture_Processor_Tables
extends Mage_Core_Model_Abstract
implements EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
const STORAGE_KEY = 'tables';
/**
* Initialize fixture resource model
*/
protected function _construct()
{
$this->_init('ecomdev_phpunit/fixture');
}
/**
* Does nothing
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Tables
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
return $this;
}
/**
* Apply tables records from fixture file
*
* @param array $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Tables
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$ignoreCleanUp = array();
// Ignore cleaning of tables if shared fixture loaded something
if ($fixture->isScopeLocal()
&& $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)) {
$ignoreCleanUp = array_keys($fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED));
}
$this->getResource()->beginTransaction();
foreach ($data as $tableEntity => $tableData) {
if (!in_array($tableEntity, $ignoreCleanUp)) {
$this->getResource()->cleanTable($tableEntity);
}
if (!empty($tableData)) {
$this->getResource()->loadTableData($tableEntity, $tableData);
}
}
$this->getResource()->commit();
$fixture->setStorageData(self::STORAGE_KEY, $data);
return $this;
}
/**
* Discard applied table records
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Tables
*/
public function discard(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$restoreTableData = array();
// Data for tables used in shared fixture
if ($fixture->isScopeLocal()
&& $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)) {
$restoreTableData = $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED);
}
$this->getResource()->beginTransaction();
foreach (array_keys($data) as $tableEntity) {
$this->getResource()->cleanTable($tableEntity);
if (isset($restoreTableData[$tableEntity])) {
$this->getResource()->loadTableData($tableEntity, $restoreTableData[$tableEntity]);
}
}
$this->getResource()->commit();
$fixture->setStorageData(self::STORAGE_KEY, null);
return $this;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Fixture_Processor_Vfs implements EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
/**
* Does nothing
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Cache
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
return $this;
}
/**
* Apply virtual file system structure
*
* @param array $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Cache
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$fixture->getVfs()->apply($data, $fixture->isScopeLocal());
return $this;
}
/**
* Discard applied virtual file system structure
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Cache
*/
public function discard(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$fixture->getVfs()->discard();
return $this;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
// Loading Spyc yaml parser,
// because Symfony component is not working properly with nested structures
require_once 'Spyc/spyc.php';
class EcomDev_PHPUnit_Model_Yaml_Loader
{
const XML_PATH_YAML_FILE_LOADERS = 'phpunit/suite/yaml/loaders';
const TYPE_FIXTURE = 'fixtures';
const TYPE_PROVIDER = 'providers';
const TYPE_EXPECTATION = 'expectations';
/**
* YAML file loaders
*
* @var EcomDev_PHPUnit_Model_Yaml_Loader_Interface[]
*/
protected $_loaders = array();
/**
* Returns arrays of loaders
*
* @return EcomDev_PHPUnit_Model_Yaml_Loader_Interface[]
*/
public function getLoaders()
{
if (empty($this->_loaders)) {
$this->_initLoaders();
}
return $this->_loaders;
}
/**
* Adds a loader to list of loders
*
* @param EcomDev_PHPUnit_Model_Yaml_Loader_Interface $loader
* @return EcomDev_PHPUnit_Model_Yaml_Loader
*/
public function addLoader(EcomDev_PHPUnit_Model_Yaml_Loader_Interface $loader)
{
$this->_loaders[] = $loader;
return $this;
}
/**
* Initializes current loaders from configuration
*
* @return EcomDev_PHPUnit_Model_Yaml_Loader
*/
protected function _initLoaders()
{
if ($loadersNode = Mage::getConfig()->getNode(self::XML_PATH_YAML_FILE_LOADERS)) {
foreach ($loadersNode->children() as $loader) {
$loaderInstance = Mage::getSingleton((string)$loader);
$this->addLoader($loaderInstance);
}
}
return $this;
}
/**
* Finds YAML file or returns false
*
* It invokes all added loaders for loading a yaml file
*
* @param string $className
* @param string $type
* @param string $name
* @return string|bool
*/
public function resolveFilePath($className, $type, $name)
{
$filePath = false;
foreach ($this->getLoaders() as $loader) {
// Break load file resolve path on first found file
if ($filePath = $loader->resolveFilePath($name, $className, $type)) {
break;
}
}
return $filePath;
}
/**
* Loads YAML file content
*
* @param string $filePath
* @return array
*/
public function load($filePath)
{
return Spyc::YAMLLoad($filePath);
}
}
<?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) 2012 EcomDev BV (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>
*/
abstract class EcomDev_PHPUnit_Model_Yaml_Loader_Abstract implements EcomDev_PHPUnit_Model_Yaml_Loader_Interface
{
/**
* Resolves YAML file path based on its filename,
* if file is not found, it should return false
*
* @param string $fileName name of the file
* @param string $relatedClassName class name from which load of yaml file is invoked
* @param string $type type of Yaml file (provider, fixture, expectation)
* @return string|bool
*/
public function resolveFilePath($fileName, $relatedClassName, $type)
{
if (strrpos($fileName, '.yaml') !== strlen($fileName) - 5) {
$fileName .= '.yaml';
}
$filePath = $this->_getFilePath($fileName, $relatedClassName, $type);
if ($filePath && file_exists($filePath)) {
return $filePath;
}
return false;
}
/**
* Returns processed file path
*
* @param string $fileName
* @param string $relatedClassName
* @param string $type
* @return string
*/
abstract protected function _getFilePath($fileName, $relatedClassName, $type);
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Yaml_Loader_Default extends EcomDev_PHPUnit_Model_Yaml_Loader_Abstract
{
/**
* Returns processed file path
*
* @param string $fileName
* @param string $relatedClassName
* @param string $type
* @return string|bool
*/
protected function _getFilePath($fileName, $relatedClassName, $type)
{
$reflection = EcomDev_Utils_Reflection::getReflection($relatedClassName);
$fileObject = new SplFileInfo($reflection->getFileName());
return $fileObject->getPath() . DS . $fileObject->getBasename('.php') . DS . $type . DS . $fileName;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Model_Yaml_Loader_Global extends EcomDev_PHPUnit_Model_Yaml_Loader_Abstract
{
/**
* Returns processed file path
*
* @param string $fileName
* @param string $relatedClassName
* @param string $type
* @return string|bool
*/
protected function _getFilePath($fileName, $relatedClassName, $type)
{
$reflection = EcomDev_Utils_Reflection::getReflection($relatedClassName);
$fileObject = new SplFileInfo($reflection->getFileName());
$basePath = $fileObject->getPath();
// While base path is within a base directory of Magento installment
while (strpos($basePath, Mage::getBaseDir()) && !is_dir($basePath . DS . $type)) {
$basePath = dirname($basePath);
}
if (basename($basePath)) {
return $basePath . DS . $type . DS .$fileName;
}
return false;
}
}
\ No newline at end of file
<?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) 2012 EcomDev BV (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>
*/
interface EcomDev_PHPUnit_Model_Yaml_Loader_Interface
{
/**
* Resolves YAML file path based on its filename,
* if file is not found, it should return false
*
* @param string $fileName name of the file
* @param string $relatedClassName class name from which load of yaml file is invoked
* @param string $type type of Yaml file (provider, fixture, expectation)
* @return string|bool
*/
public function resolveFilePath($fileName, $relatedClassName, $type);
}
\ No newline at end of file
<?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
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*
* @author Colin Mollenhour <http://colin.mollenhour.com>
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
class EcomDev_PHPUnit_Model_Yaml_Loader_Module extends EcomDev_PHPUnit_Model_Yaml_Loader_Abstract
{
/**
* Returns processed file path based on module test directory
*
* @param string $fileName
* @param string $relatedClassName
* @param string $type
* @return string|bool
*/
protected function _getFilePath($fileName, $relatedClassName, $type)
{
$moduleName = EcomDev_PHPUnit_Test_Case_Util::getModuleNameByClassName($relatedClassName);
if (preg_match('#^~(?<module>[^/]*)/(?<fileName>.*)$#', $fileName, $matches)) {
$fileName = $matches['fileName'];
if(!empty($matches['module'])) {
$moduleName = $matches['module'];
}
}
$filePath = Mage::getModuleDir('', $moduleName) . DS . 'Test' . DS . $type . DS . $fileName;
return false;
}
}
...@@ -16,10 +16,6 @@ ...@@ -16,10 +16,6 @@
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org> * @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/ */
// Loading Spyc yaml parser,
// becuase Symfony component is not working propertly with nested associations
require_once 'Spyc/spyc.php';
/** /**
* Basic test case class * Basic test case class
* *
...@@ -42,6 +38,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -42,6 +38,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* List of system registry values replaced by test case * List of system registry values replaced by test case
* *
* @var array * @var array
* @deprecated since 0.3.0
*/ */
protected $_replacedRegistry = array(); protected $_replacedRegistry = array();
...@@ -58,6 +55,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -58,6 +55,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* if was set in test method * if was set in test method
* *
* @var Mage_Core_Model_Store * @var Mage_Core_Model_Store
* @deprecated since 0.3.0
*/ */
protected $_originalStore = null; protected $_originalStore = null;
...@@ -90,8 +88,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -90,8 +88,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
/** /**
* Asserts that event was dispatched at least once * Asserts that event was dispatched at least once
* *
* @param string|array $event * @param array|string $eventName
* @param string $message
*/ */
public static function assertEventDispatched($eventName) public static function assertEventDispatched($eventName)
{ {
...@@ -110,8 +107,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -110,8 +107,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
/** /**
* Asserts that event was not dispatched * Asserts that event was not dispatched
* *
* @param string|array $event * @param string|array $eventName
* @param string $message
*/ */
public static function assertEventNotDispatched($eventName) public static function assertEventNotDispatched($eventName)
{ {
...@@ -178,7 +174,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -178,7 +174,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* is matched expected JSON structure * is matched expected JSON structure
* *
* @param array $expectedValue * @param array $expectedValue
* @param strign $matchType * @param string $matchType
* @return EcomDev_PHPUnit_Constraint_Json * @return EcomDev_PHPUnit_Constraint_Json
*/ */
public static function matchesJson(array $expectedValue, $matchType = EcomDev_PHPUnit_Constraint_Json::MATCH_AND) public static function matchesJson(array $expectedValue, $matchType = EcomDev_PHPUnit_Constraint_Json::MATCH_AND)
...@@ -219,7 +215,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -219,7 +215,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $string * @param string $string
* @param array $expectedValue * @param array $expectedValue
* @param string $message * @param string $message
* @param strign $matchType * @param string $matchType
*/ */
public static function assertJsonMatch($string, array $expectedValue, $message = '', public static function assertJsonMatch($string, array $expectedValue, $message = '',
$matchType = EcomDev_PHPUnit_Constraint_Json::MATCH_AND) $matchType = EcomDev_PHPUnit_Constraint_Json::MATCH_AND)
...@@ -327,35 +323,10 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -327,35 +323,10 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $type * @param string $type
* @param string $classAlias * @param string $classAlias
* @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock * @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock
* @return EcomDev_PHPUnit_Test_Case
*/ */
protected function replaceByMock($type, $classAlias, $mock) protected function replaceByMock($type, $classAlias, $mock)
{ {
if ($mock instanceof PHPUnit_Framework_MockObject_MockBuilder) { EcomDev_PHPUnit_Test_Case_Util::replaceByMock($type, $classAlias, $mock);
$mock = $mock->getMock();
} elseif (!$mock instanceof PHPUnit_Framework_MockObject_MockObject) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'PHPUnit_Framework_MockObject_MockObject'
);
}
// Remove addition of /data suffix if version is more than 1.6.x
if (version_compare(Mage::getVersion(), '1.6.0.0', '<') && $type == 'helper' && strpos($classAlias, '/') === false) {
$classAlias .= '/data';
}
if (in_array($type, array('model', 'resource_model'))) {
$this->app()->getConfig()->replaceInstanceCreation($type, $classAlias, $mock);
$type = str_replace('model', 'singleton', $type);
} elseif ($type == 'block') {
$this->app()->getLayout()->replaceBlockCreation($classAlias, $mock);
}
if (in_array($type, array('singleton', 'resource_singleton', 'helper'))) {
$registryPath = '_' . $type . '/' . $classAlias;
$this->replaceRegistry($registryPath, $mock);
}
return $this; return $this;
} }
...@@ -364,14 +335,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -364,14 +335,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* *
* @param string $key * @param string $key
* @param mixed $value * @param mixed $value
* @return EcomDev_PHPUnit_Test_Case
*/ */
protected function replaceRegistry($key, $value) protected function replaceRegistry($key, $value)
{ {
$oldValue = Mage::registry($key); EcomDev_PHPUnit_Test_Case_Util::replaceRegistry($key, $value);
$this->app()->replaceRegistry($key, $value);
$this->_replacedRegistry[$key] = $oldValue;
return $this; return $this;
} }
...@@ -379,31 +347,20 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -379,31 +347,20 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* Shortcut for expectation data object retrieval * Shortcut for expectation data object retrieval
* Can be called with arguments array or in usual method * Can be called with arguments array or in usual method
* *
* @param string|array $pathFormat * @param string|array $firstArgument
* @param mixed $arg1 * @optional @param mixed $arg1
* @param mixed $arg2 ... * @optional @param mixed $arg2 ...
* @return Varien_Object * @return Varien_Object
*/ */
protected function expected($firstArgument = null) protected function expected($firstArgument = null)
{ {
if (!$this->getExpectation()->isLoaded()) {
$this->getExpectation()->loadByTestCase($this);
$this->getExpectation()->apply();
}
if (!is_array($firstArgument)) { if (!is_array($firstArgument)) {
$arguments = func_get_args(); $arguments = func_get_args();
} else { } else {
$arguments = $firstArgument; $arguments = $firstArgument;
} }
$pathFormat = null; return EcomDev_PHPUnit_Test_Case_Util::expected($this, $arguments);
if ($arguments) {
$pathFormat = array_shift($arguments);
}
return $this->getExpectation()
->getDataObject($pathFormat, $arguments);
} }
/** /**
...@@ -640,6 +597,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -640,6 +597,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* Retrieves fixture model singleton * Retrieves fixture model singleton
* *
* @return EcomDev_PHPUnit_Model_Fixture * @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/ */
protected static function getFixture() protected static function getFixture()
{ {
...@@ -650,6 +608,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -650,6 +608,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* Returns expectation model singleton * Returns expectation model singleton
* *
* @return EcomDev_PHPUnit_Model_Expectation * @return EcomDev_PHPUnit_Model_Expectation
* @deprecated since 0.3.0
*/ */
protected function getExpectation() protected function getExpectation()
{ {
...@@ -668,7 +627,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -668,7 +627,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/ */
protected static function getLoadableClassAlias($type, $configPath) protected static function getLoadableClassAlias($type, $configPath)
{ {
return EcomDev_PHPUnit_Test_Case::getLoadableClassAlias(get_called_class(), $type, $configPath); return EcomDev_PHPUnit_Test_Case_Util::getLoadableClassAlias(get_called_class(), $type, $configPath);
} }
/** /**
...@@ -720,18 +679,6 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -720,18 +679,6 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
return EcomDev_PHPUnit_Test_Case_Util::getYamlFilePath($className, $type, $name); return EcomDev_PHPUnit_Test_Case_Util::getYamlFilePath($className, $type, $name);
} }
/**
* Initializes a particular test environment
*
* (non-PHPdoc)
* @see PHPUnit_Framework_TestCase::setUp()
*/
protected function setUp()
{
$this->app()->resetDispatchedEvents();
parent::setUp();
}
/** /**
* Implements default data provider functionality, * Implements default data provider functionality,
* returns array data loaded from Yaml file with the same name as test method * returns array data loaded from Yaml file with the same name as test method
...@@ -741,15 +688,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -741,15 +688,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/ */
public function dataProvider($testName) public function dataProvider($testName)
{ {
$this->setName($testName); return EcomDev_PHPUnit_Test_Case_Util::dataProvider(get_called_class(), $testName);
$filePath = $this->getYamlFilePath('providers');
$this->setName(null);
if (!$filePath) {
throw new RuntimeException('Unable to load data provider for the current test');
}
return Spyc::YAMLLoad($filePath);
} }
/** /**
...@@ -760,35 +699,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase ...@@ -760,35 +699,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/ */
public function setCurrentStore($store) public function setCurrentStore($store)
{ {
if (!$this->_originalStore) { EcomDev_PHPUnit_Test_Case_Util::setCurrentStore($store);
$this->_originalStore = $this->app()->getStore();
}
$this->app()->setCurrentStore(
$this->app()->getStore($store)
);
return $this; return $this;
} }
/**
* Performs a clean up after a particular test was run
* (non-PHPdoc)
* @see PHPUnit_Framework_TestCase::tearDown()
*/
protected function tearDown()
{
if ($this->_originalStore) { // Remove store scope, that was set in test
$this->app()->setCurrentStore($this->_originalStore);
$this->_originalStore = null;
}
$this->app()->getConfig()->flushReplaceInstanceCreation();
$this->app()->getLayout()->flushReplaceBlockCreation();
foreach ($this->_replacedRegistry as $registryPath => $originalValue) {
$this->app()->replaceRegistry($registryPath, $originalValue);
parent::tearDown();
}
} }
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Test_Case_Util class EcomDev_PHPUnit_Test_Case_Util
{ {
const XML_PATH_DEFAULT_FIXTURE_MODEL = 'phpunit/suite/fixture/model'; const XML_PATH_DEFAULT_FIXTURE_MODEL = 'phpunit/suite/fixture/model';
const XML_PATH_DEFAULT_EXPECTATION_MODEL = 'phpunit/suite/expectation/model'; const XML_PATH_DEFAULT_EXPECTATION_MODEL = 'phpunit/suite/expectation/model';
const XML_PATH_DEFAULT_YAML_LOADER_MODEL = 'phpunit/suite/yaml/model';
/**
* List of replaced registry keys for current test case run
*
* @var array
*/
protected static $replacedRegistry = array();
/**
* Original store before first setCurrentStore() call
*
* @var int|string|Mage_Core_Model_Store|null
*/
protected static $originalStore = null;
/**
* Current expectation model alias
*
* @var string
*/
protected static $expectationModelAlias = null;
/**
* Current fixture model alias
*
* @var string
*/
protected static $fixtureModelAlias = null;
/**
* Current yaml loader model alias
*
* @var string
*/
protected static $yamlLoaderModelAlias = null;
/**
* Module name by class name
*
* @var string[]
*/
protected static $moduleNameByClassName = array();
/** /**
* Returns app for test case, created for type hinting * Returns app for test case, created for type hinting
...@@ -17,33 +78,221 @@ class EcomDev_PHPUnit_Test_Case_Util ...@@ -17,33 +78,221 @@ class EcomDev_PHPUnit_Test_Case_Util
} }
/** /**
* Retrieves the module name for current test case * Returns yaml loader model instance
*
* @param string|null $testCaseClass
* @return EcomDev_PHPUnit_Model_Yaml_Loader
*/
public static function getYamlLoader($testCaseClass = null)
{
if ($testCaseClass !== null) {
self::$yamlLoaderModelAlias = self::getLoadableClassAlias(
$testCaseClass,
'yaml',
self::XML_PATH_DEFAULT_YAML_LOADER_MODEL
);
} elseif (self::$fixtureModelAlias === null) {
self::$yamlLoaderModelAlias = self::getLoadableClassAlias(
get_called_class(), // Just fallback to current test util
'yaml',
self::XML_PATH_DEFAULT_YAML_LOADER_MODEL
);
}
return Mage::getSingleton(self::$yamlLoaderModelAlias);
}
/**
* Loads YAML file based on loaders logic
*
* @param string $className class name for looking fixture files
* @param string $type type of YAML data (fixtures,expectations,providers)
* @param string $name the file name for loading
* @return string|boolean
*/
public static function getYamlFilePath($className, $type, $name)
{
return self::getYamlLoader($className)->resolveFilePath($className, $type, $name);
}
/**
* Retrieves fixture model singleton
*
* @param string|null $testCaseClass
* @return EcomDev_PHPUnit_Model_Fixture
* @throws RuntimeException
*/
public static function getFixture($testCaseClass = null)
{
if ($testCaseClass !== null) {
self::$fixtureModelAlias = self::getLoadableClassAlias(
$testCaseClass,
'fixture',
self::XML_PATH_DEFAULT_FIXTURE_MODEL
);
} elseif (self::$fixtureModelAlias === null) {
self::$fixtureModelAlias = self::getLoadableClassAlias(
get_called_class(), // Just fallback to current test util
'fixture',
self::XML_PATH_DEFAULT_FIXTURE_MODEL
);
}
$fixture = Mage::getSingleton(self::$fixtureModelAlias);
if (!$fixture instanceof EcomDev_PHPUnit_Model_Fixture_Interface) {
throw new RuntimeException('Fixture model should implement EcomDev_PHPUnit_Model_Fixture_Interface interface');
}
$storage = Mage::registry(EcomDev_PHPUnit_Model_App::REGISTRY_PATH_SHARED_STORAGE);
if (!$storage instanceof Varien_Object) {
throw new RuntimeException('Fixture storage object was not initialized during test application setup');
}
$fixture->setStorage(
Mage::registry(EcomDev_PHPUnit_Model_App::REGISTRY_PATH_SHARED_STORAGE)
);
return $fixture;
}
/**
* Returns expectation model singleton
*
* @param string|null $testCaseClass
* @return EcomDev_PHPUnit_Model_Expectation
*/
public static function getExpectation($testCaseClass = null)
{
if ($testCaseClass !== null) {
self::$expectationModelAlias = self::getLoadableClassAlias(
$testCaseClass,
'expectation',
self::XML_PATH_DEFAULT_EXPECTATION_MODEL
);
} elseif (self::$expectationModelAlias === null) {
self::$expectationModelAlias = self::getLoadableClassAlias(
get_called_class(), // Just fallback to current test util
'expectation',
self::XML_PATH_DEFAULT_EXPECTATION_MODEL
);
}
return Mage::getSingleton(self::$expectationModelAlias);
}
/**
* Shortcut for expectation data object retrieval
* Can be called with arguments array or in usual method
* *
* @param PHPUnit_Framework_TestCase $testCase * @param PHPUnit_Framework_TestCase $testCase
* @return string * @param string|array $firstArgument
* @throws RuntimeException if module name was not found for the passed class name * @optional @param mixed $arg1
* @optional @param mixed $arg2
* @return Varien_Object
*/ */
public static function getModuleName(PHPUnit_Framework_TestCase $testCase) public static function expected(PHPUnit_Framework_TestCase $testCase, $firstArgument = null)
{ {
return self::app()->getModuleNameByClassName($testCase); if (!self::getExpectation(get_class($testCase))->isLoaded()) {
self::getExpectation()->loadByTestCase($testCase);
self::getExpectation()->apply();
}
if (!is_array($firstArgument)) {
$arguments = func_get_args();
array_shift($arguments); // Remove test case from arguments
} else {
$arguments = $firstArgument;
}
$pathFormat = null;
if ($arguments) {
$pathFormat = array_shift($arguments);
}
return self::getExpectation()
->getDataObject($pathFormat, $arguments);
} }
/** /**
* Retrieves module name from call stack objects * Loads data provider based on test class name and test name
*
* @param string $className
* @param string $testName
*
* @return array
* @throws RuntimeException
*/
public static function dataProvider($className, $testName)
{
$dataProviderFiles = array();
if ($annotations = self::getAnnotationByNameFromClass($className, 'dataProviderFile', array('class', 'method'), $testName)) {
foreach ($annotations as $name) {
$filePath = self::getYamlLoader($className)
->resolveFilePath($className, EcomDev_PHPUnit_Model_Yaml_Loader::TYPE_PROVIDER, $name);
if (!$filePath) {
throw new RuntimeException(sprintf('Unable to load data provider for path %s', $name));
}
$dataProviderFiles[] = $filePath;
}
} else {
$filePath = self::getYamlLoader($className)
->resolveFilePath($className, EcomDev_PHPUnit_Model_Yaml_Loader::TYPE_PROVIDER, $testName);
if (!$filePath) {
throw new RuntimeException('Unable to load data provider for the current test');
}
$dataProviderFiles[] = $filePath;
}
$providerData = array();
foreach ($dataProviderFiles as $file) {
$providerData = array_merge_recursive($providerData, self::getYamlLoader()->load($file));
}
return $providerData;
}
/**
* Retrieves loadable class alias from annotation or configuration node
* E.g. class alias for fixture model can be specified via @fixtureModel annotation
* *
* @param string $className
* @param string $type
* @param string $configPath
* @return string * @return string
* @throws RuntimeException if assertion is called in not from EcomDev_PHPUnit_Test_Case
*/ */
public static function getModuleNameFromCallStack() public static function getLoadableClassAlias($className, $type, $configPath)
{ {
$backTrace = debug_backtrace(true); $annotationValue = self::getAnnotationByNameFromClass(
foreach ($backTrace as $call) { $className,
if (isset($call['object']) && $call['object'] instanceof PHPUnit_Framework_TestCase) { $type .'Model'
return self::getModuleName($call['object']); );
if (current($annotationValue)) {
$classAlias = current($annotationValue);
} else {
$classAlias = (string) self::app()->getConfig()->getNode($configPath);
} }
return $classAlias;
} }
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 the module name for current test case
*
* @param PHPUnit_Framework_TestCase $testCase
* @return string
* @throws RuntimeException if module name was not found for the passed class name
*/
public static function getModuleName(PHPUnit_Framework_TestCase $testCase)
{
return self::getModuleNameByClassName($testCase);
} }
/** /**
...@@ -67,7 +316,7 @@ class EcomDev_PHPUnit_Test_Case_Util ...@@ -67,7 +316,7 @@ class EcomDev_PHPUnit_Test_Case_Util
$annotation = array(); $annotation = array();
// Walk-through sources for annotation retrieval // Walkthrough sources for annotation retrieval
foreach ($sources as $source) { foreach ($sources as $source) {
if (isset($allAnnotations[$source][$name])) { if (isset($allAnnotations[$source][$name])) {
$annotation = array_merge( $annotation = array_merge(
...@@ -80,139 +329,164 @@ class EcomDev_PHPUnit_Test_Case_Util ...@@ -80,139 +329,164 @@ class EcomDev_PHPUnit_Test_Case_Util
return $annotation; return $annotation;
} }
/** /**
* Retrieves loadable class alias from annotation or configuration node * Retrieves module name from call stack objects
* E.g. class alias for fixture model can be specified via @fixtureModel annotation
* *
* @param string $className
* @param string $type
* @param string $configPath
* @return string * @return string
* @throws RuntimeException if assertion is called in not from EcomDev_PHPUnit_Test_Case
*/ */
protected static function getLoadableClassAlias($className, $type, $configPath) public static function getModuleNameFromCallStack()
{ {
$annotationValue = self::getAnnotationByNameFromClass( $backTrace = debug_backtrace(true);
$className, foreach ($backTrace as $call) {
$type .'Model' if (isset($call['object']) && $call['object'] instanceof PHPUnit_Framework_TestCase) {
); return self::getModuleName($call['object']);
}
if (current($annotationValue)) {
$classAlias = current($annotationValue);
} else {
$classAlias = (string) self::app()->getConfig()->getNode($configPath);
} }
return $classAlias; throw new RuntimeException('Unable to retrieve module name from call stack, because assertion is not called from PHPUnit_Framework_Test_Case based class method');
} }
/** /**
* Returns expectation model singleton * Set current store scope for test
* *
* @param string $testCaseClassName * @param int|string|Mage_Core_Model_Store $store
* @return EcomDev_PHPUnit_Model_Expectation * @return void
*/ */
public static function getExpectation($testCaseClassName) public static function setCurrentStore($store)
{ {
return Mage::getSingleton( if (!self::$originalStore) {
self::getLoadableClassAlias( self::$originalStore = self::app()->getStore();
$testCaseClassName, }
'expectation',
self::XML_PATH_DEFAULT_EXPECTATION_MODEL self::app()->setCurrentStore(
) self::app()->getStore($store)
); );
} }
/** /**
* Set associated module name for a class name,
* Usually used for making possible dependency injection in the test cases
* *
* @param PHPUnit_Framework_TestCase $testCase
* *
* @param string $className
* @param string $moduleName
* @return array
*/ */
public static function loadExpectation(PHPUnit_Framework_TestCase $testCase) public static function setModuleNameForClassName($className, $moduleName)
{ {
self::$moduleNameByClassName[$className] = $moduleName;
} }
/** /**
* Retrieves fixture model singleton * Returns module name for a particular object
* *
* @param string $testCaseClassName * @param string|object $className
* @return EcomDev_PHPUnit_Model_Fixture * @throws RuntimeException if module name was not found for the passed class name
* @throws RuntimeException * @return string
*/ */
public static function getFixture($testCaseClassName) public static function getModuleNameByClassName($className)
{ {
$fixture = Mage::getSingleton( if (is_object($className)) {
self::getLoadableClassAlias( $className = get_class($className);
$testCaseClassName,
'fixture',
self::XML_PATH_DEFAULT_FIXTURE_MODEL
)
);
if (!$fixture instanceof EcomDev_PHPUnit_Model_Fixture_Interface) {
throw new RuntimeException('Fixture model should implement EcomDev_PHPUnit_Model_Fixture_Interface interface');
} }
$storage = Mage::registry(EcomDev_PHPUnit_Model_App::REGISTRY_PATH_SHARED_STORAGE); if (!isset(self::$moduleNameByClassName[$className])) {
// Try to find the module name by class name
$moduleName = false;
foreach (Mage::getConfig()->getNode('modules')->children() as $module) {
if (strpos($className, $module->getName()) === 0) {
$moduleName = $module->getName();
break;
}
}
if (!$storage instanceof Varien_Object) { if (!$moduleName) {
throw new RuntimeException('Fixture storage object was not initialized during test application setup'); throw new RuntimeException('Cannot to find the module name for class name: ' . $className);
} }
$fixture->setStorage( self::setModuleNameForClassName($className, $moduleName);
Mage::registry(EcomDev_PHPUnit_Model_App::REGISTRY_PATH_SHARED_STORAGE) }
);
return $fixture; return self::$moduleNameByClassName[$className];
} }
/** /**
* Loads YAML file from directory inside of the unit test class or * Replaces Magento resource by mock object
* the directory inside the module directory if name is prefixed with ~/
* or from another module if name is prefixed with ~My_Module/
* *
* @param string $className class name for looking fixture files * @param string $type
* @param string $type type of YAML data (fixtures,expectations,dataproviders) * @param string $classAlias
* @param string $name the file name for loading * @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock
* @return string|boolean * @return void
*
* @throws InvalidArgumentException
*/ */
public static function getYamlFilePath($className, $type, $name) public static function replaceByMock($type, $classAlias, $mock)
{ {
if (strrpos($name, '.yaml') !== strlen($name) - 5) { if ($mock instanceof PHPUnit_Framework_MockObject_MockBuilder) {
$name .= '.yaml'; $mock = $mock->getMock();
} elseif (!$mock instanceof PHPUnit_Framework_MockObject_MockObject) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'PHPUnit_Framework_MockObject_MockObject'
);
} }
$classFileObject = new SplFileInfo( // Remove addition of /data suffix if version is more than 1.6.x
EcomDev_Utils_Reflection::getRelflection($className)->getFileName() if (version_compare(Mage::getVersion(), '1.6.0.0', '<') && $type == 'helper' && strpos($classAlias, '/') === false) {
); $classAlias .= '/data';
}
// When prefixed with ~/ or ~My_Module/, load from the module's Test/<type> directory if (in_array($type, array('model', 'resource_model'))) {
if (preg_match('#^~(?<module>[^/]*)/(?<path>.*)$#', $name, $matches)) { self::app()->getConfig()->replaceInstanceCreation($type, $classAlias, $mock);
$name = $matches['path']; $type = str_replace('model', 'singleton', $type);
if( ! empty($matches['module'])) { } elseif ($type == 'block') {
$moduleName = $matches['module']; self::app()->getLayout()->replaceBlockCreation($classAlias, $mock);
} else {
$moduleName = substr($className, 0, strpos($className, '_Test_'));;
} }
$filePath = Mage::getModuleDir('', $moduleName) . DS . 'Test' . DS;
if (in_array($type, array('singleton', 'resource_singleton', 'helper'))) {
$registryPath = '_' . $type . '/' . $classAlias;
self::replaceRegistry($registryPath, $mock);
} }
// Otherwise load from the Class/<type> directory
else {
$filePath = $classFileObject->getPath() . DS
. $classFileObject->getBasename('.php') . DS;
} }
$filePath .= $type . DS . $name;
if (file_exists($filePath)) { /**
return $filePath; * Replaces value in Magento system registry
*
* @param string $key
* @param mixed $value
* @return void
*/
public static function replaceRegistry($key, $value)
{
$oldValue = Mage::registry($key);
self::app()->replaceRegistry($key, $value);
self::$replacedRegistry[$key] = $oldValue;
} }
return false; /**
* Called for each test case
*
*/
public static function setUp()
{
self::app()->resetDispatchedEvents();
} }
/**
* Called for each test case
*
*/
public static function tearDown()
{
if (self::$originalStore) {
self::app()->setCurrentStore(self::$originalStore);
self::$originalStore = null;
}
self::app()->getConfig()->flushReplaceInstanceCreation();
self::app()->getLayout()->flushReplaceBlockCreation();
foreach (self::$replacedRegistry as $registryPath => $originalValue) {
self::app()->replaceRegistry($registryPath, $originalValue);
}
}
} }
<?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) 2012 EcomDev BV (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>
*/
class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
{ {
...@@ -20,7 +36,7 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -20,7 +36,7 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
protected function getAppReflection() protected function getAppReflection()
{ {
$appClass = (string) Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_APP); $appClass = (string) Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_APP);
$reflectionClass = EcomDev_Utils_Reflection::getRelflection($appClass); $reflectionClass = EcomDev_Utils_Reflection::getReflection($appClass);
return $reflectionClass; return $reflectionClass;
} }
...@@ -34,12 +50,12 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -34,12 +50,12 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
{ {
if ($this->firstLevelTestSuite === null) { if ($this->firstLevelTestSuite === null) {
// Apply app substitution for tests // Apply app substitution for tests
if ($this->getAppReflection()->hasMethod('applyTestScope')) { if ($this->getAppReflection()->hasMethod('applyTestScope')) {
$this->getAppReflection()->getMethod('applyTestScope')->invoke(null); $this->getAppReflection()->getMethod('applyTestScope')->invoke(null);
} }
$this->firstLevelTestSuite = $suite; $this->firstLevelTestSuite = $suite;
echo 'Starting suite...' . $suite->getName();
} }
if (EcomDev_Utils_Reflection::getRestrictedPropertyValue($suite, 'testCase')) { if (EcomDev_Utils_Reflection::getRestrictedPropertyValue($suite, 'testCase')) {
...@@ -64,19 +80,20 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -64,19 +80,20 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
*/ */
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
{ {
if (EcomDev_Utils_Reflection::getRestrictedPropertyValue($suite, 'testCase')) {
EcomDev_PHPUnit_Test_Case_Util::getFixture($suite->getName())
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)
->discard();
}
if ($this->firstLevelTestSuite === $suite) { if ($this->firstLevelTestSuite === $suite) {
$this->firstLevelTestSuite = null; $this->firstLevelTestSuite = null;
echo 'Finishing test suite...' . $suite->getName();
// Discard test scope app // Discard test scope app
if ($this->getAppReflection()->hasMethod('discardTestScope')) { if ($this->getAppReflection()->hasMethod('discardTestScope')) {
$this->getAppReflection()->getMethod('discardTestScope')->invoke(null); $this->getAppReflection()->getMethod('discardTestScope')->invoke(null);
} }
} }
if (EcomDev_Utils_Reflection::getRestrictedPropertyValue($suite, 'testCase')) {
EcomDev_PHPUnit_Test_Case_Util::getFixture($suite->getName())
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)
->discard();
}
} }
/** /**
...@@ -87,13 +104,15 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -87,13 +104,15 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
public function startTest(PHPUnit_Framework_Test $test) public function startTest(PHPUnit_Framework_Test $test)
{ {
if ($test instanceof PHPUnit_Framework_TestCase) { if ($test instanceof PHPUnit_Framework_TestCase) {
EcomDev_PHPUnit_Test_Case_Util::getFixture($test->getName()) EcomDev_PHPUnit_Test_Case_Util::getFixture(get_class($test))
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL) ->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL)
->loadByTestCase($test); ->loadByTestCase($test);
$annotations = $this->getAnnotations(); $annotations = $test->getAnnotations();
self::getFixture() EcomDev_PHPUnit_Test_Case_Util::getFixture()
->setOptions($annotations['method']) ->setOptions($annotations['method'])
->apply(); ->apply();
EcomDev_PHPUnit_Test_Case_Util::setUp();
} }
} }
...@@ -106,13 +125,15 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -106,13 +125,15 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
public function endTest(PHPUnit_Framework_Test $test, $time) public function endTest(PHPUnit_Framework_Test $test, $time)
{ {
if ($test instanceof PHPUnit_Framework_TestCase) { if ($test instanceof PHPUnit_Framework_TestCase) {
EcomDev_PHPUnit_Test_Case_Util::getFixture($test->getName()) EcomDev_PHPUnit_Test_Case_Util::getFixture(get_class($test))
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL) ->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL)
->discard(); // Clear applied fixture ->discard(); // Clear applied fixture
if (EcomDev_PHPUnit_Test_Case_Util::getExpectation($test->getName())->isLoaded()) { if (EcomDev_PHPUnit_Test_Case_Util::getExpectation(get_class($test))->isLoaded()) {
EcomDev_PHPUnit_Test_Case_Util::getExpectation($test->getName())->discard(); EcomDev_PHPUnit_Test_Case_Util::getExpectation(get_class($test))->discard();
} }
EcomDev_PHPUnit_Test_Case_Util::tearDown();
} }
} }
...@@ -158,8 +179,6 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -158,8 +179,6 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
* @param PHPUnit_Framework_Test $test * @param PHPUnit_Framework_Test $test
* @param Exception $e * @param Exception $e
* @param float $time * @param float $time
*
* @since Method available since Release 3.0.0
*/ */
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{ {
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org> * @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/ */
/** /**
* Test suite for Magento * Test suite for Magento
* *
...@@ -34,27 +33,6 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite ...@@ -34,27 +33,6 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
const CACHE_TAG = 'ECOMDEV_PHPUNIT'; const CACHE_TAG = 'ECOMDEV_PHPUNIT';
const CACHE_TYPE = 'ecomdev_phpunit'; const CACHE_TYPE = 'ecomdev_phpunit';
/**
* Setting up test scope for Magento
* (non-PHPdoc)
* @see PHPUnit_Framework_TestSuite::setUp()
* @deprecated since 0.3.0
*/
protected function setUp()
{
}
/**
* Returning Magento to the state before suite was run
* (non-PHPdoc)
* @see PHPUnit_Framework_TestSuite::tearDown()
*/
protected function tearDown()
{
}
/** /**
* This method loads all available test suites for PHPUnit * This method loads all available test suites for PHPUnit
* *
...@@ -64,7 +42,7 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite ...@@ -64,7 +42,7 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
{ {
$groups = Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_GROUPS); $groups = Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_GROUPS);
$modules = Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_MODULES); $modules = Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_MODULES);
$testSuiteClass = EcomDev_Utils_Reflection::getRelflection((string) Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_SUITE)); $testSuiteClass = EcomDev_Utils_Reflection::getReflection((string) Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_SUITE));
if (!$testSuiteClass->isSubclassOf('EcomDev_PHPUnit_Test_Suite_Group')) { if (!$testSuiteClass->isSubclassOf('EcomDev_PHPUnit_Test_Suite_Group')) {
new RuntimeException('Test Suite class should be extended from EcomDev_PHPUnit_Test_Suite_Group'); new RuntimeException('Test Suite class should be extended from EcomDev_PHPUnit_Test_Suite_Group');
...@@ -146,7 +124,7 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite ...@@ -146,7 +124,7 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
// Add unit test case only // Add unit test case only
// if it is a valid class extended from EcomDev_PHPUnit_Test_Case // if it is a valid class extended from EcomDev_PHPUnit_Test_Case
if (class_exists($className, true)) { if (class_exists($className, true)) {
$reflectionClass = EcomDev_Utils_Reflection::getRelflection($className); $reflectionClass = EcomDev_Utils_Reflection::getReflection($className);
if (!$reflectionClass->isSubclassOf('EcomDev_PHPUnit_Test_Case') if (!$reflectionClass->isSubclassOf('EcomDev_PHPUnit_Test_Case')
|| $reflectionClass->isAbstract()) { || $reflectionClass->isAbstract()) {
continue; continue;
......
...@@ -42,7 +42,7 @@ class EcomDev_PHPUnit_Test_Suite_Group extends PHPUnit_Framework_TestSuite ...@@ -42,7 +42,7 @@ class EcomDev_PHPUnit_Test_Suite_Group extends PHPUnit_Framework_TestSuite
public function __construct($theClass = '', $groups = array()) public function __construct($theClass = '', $groups = array())
{ {
if (!$theClass instanceof ReflectionClass) { if (!$theClass instanceof ReflectionClass) {
$theClass = EcomDev_Utils_Reflection::getRelflection($theClass); $theClass = EcomDev_Utils_Reflection::getReflection($theClass);
} }
// Check annotations for test case name // Check annotations for test case name
......
<?php <?php
if (version_compare(PHP_VERSION, '5.3', '<')) { if (version_compare(PHP_VERSION, '5.3', '<')) {
exit('Magento Unit Tests can run only on PHP version higher then 5.3'); echo 'Magento Unit Tests can run only on PHP version higher then 5.3';
exit(1);
} }
$_baseDir = getcwd();
$fileDir = dirname(__FILE__);
// Include Mage file by detecting app root // Include Mage file by detecting app root
require_once substr($fileDir, 0, strpos($fileDir, 'app' . DIRECTORY_SEPARATOR)) . 'app/Mage.php'; require_once $_baseDir . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'Mage.php';
if (!Mage::isInstalled()) { if (!Mage::isInstalled()) {
exit('Magento Unit Tests can run only on installed version'); echo 'Magento Unit Tests can run only on installed version';
exit(1);
} }
/* Replace server variables for proper file naming */ /* Replace server variables for proper file naming */
$_SERVER['SCRIPT_NAME'] = dirname(__FILE__) . DS . 'index.php'; $_SERVER['SCRIPT_NAME'] = $_baseDir . DS . 'index.php';
$_SERVER['SCRIPT_FILENAME'] = dirname(__FILE__) . DS . 'index.php'; $_SERVER['SCRIPT_FILENAME'] = $_baseDir . DS . 'index.php';
Mage::app('admin'); Mage::app('admin');
Mage::getConfig()->init(); Mage::getConfig()->init();
...@@ -45,6 +45,14 @@ ...@@ -45,6 +45,14 @@
</global> </global>
<phpunit> <phpunit>
<suite> <suite>
<yaml>
<model>ecomdev_phpunit/yaml_loader</model>
<loaders>
<default>ecomdev_phpunit/yaml_loader_default</default>
<module>ecomdev_phpunit/yaml_loader_module</module>
<global>ecomdev_phpunit/yaml_loader_global</global>
</loaders>
</yaml>
<!-- The names of directories inside Test for recognizion of tests per group --> <!-- The names of directories inside Test for recognizion of tests per group -->
<groups> <groups>
<models>Model</models> <models>Model</models>
...@@ -70,6 +78,15 @@ ...@@ -70,6 +78,15 @@
<fixture> <fixture>
<!-- Default model for loading of fixtures --> <!-- Default model for loading of fixtures -->
<model>ecomdev_phpunit/fixture</model> <model>ecomdev_phpunit/fixture</model>
<processors>
<scope>ecomdev_phpunit/fixture_processor_scope</scope>
<config>ecomdev_phpunit/fixture_processor_config</config>
<config_xml>ecomdev_phpunit/fixture_processor_config</config_xml>
<cache_options>ecomdev_phpunit/fixture_processor_cache</cache_options>
<eav>ecomdev_phpunit/fixture_processor_eav</eav>
<tables>ecomdev_phpunit/fixture_processor_tables</tables>
<vfs>ecomdev_phpunit/fixture_processor_vfs</vfs>
</processors>
<eav> <eav>
<!-- Here goes the list of fixture loaders for EAV <!-- Here goes the list of fixture loaders for EAV
If no fixture loader is specified for entity, then default will be used If no fixture loader is specified for entity, then default will be used
......
...@@ -83,7 +83,7 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract ...@@ -83,7 +83,7 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
*/ */
public function __construct($type, $expectedValue = null) public function __construct($type, $expectedValue = null)
{ {
$reflection = EcomDev_Utils_Reflection::getRelflection(get_class($this)); $reflection = EcomDev_Utils_Reflection::getReflection(get_class($this));
$types = array(); $types = array();
foreach ($reflection->getConstants() as $name => $constant) { foreach ($reflection->getConstants() as $name => $constant) {
if (strpos($name, 'TYPE_') === 0) { if (strpos($name, 'TYPE_') === 0) {
......
...@@ -103,11 +103,14 @@ class EcomDev_PHPUnit_Constraint_Json extends EcomDev_PHPUnit_Constraint_Abstrac ...@@ -103,11 +103,14 @@ class EcomDev_PHPUnit_Constraint_Json extends EcomDev_PHPUnit_Constraint_Abstrac
$decodedJson = Zend_Json::decode($other); $decodedJson = Zend_Json::decode($other);
$this->setActualValue($decodedJson); $this->setActualValue($decodedJson);
$intersection = array_intersect_assoc(
$this->_actualValue, $intersection = array_intersect(
$this->_expectedValue array_keys($this->_actualValue),
array_keys($this->_expectedValue)
); );
// @todo make it more recursive
switch ($this->_matchType) { switch ($this->_matchType) {
case self::MATCH_OR: case self::MATCH_OR:
$matched = !empty($intersection); $matched = !empty($intersection);
......
...@@ -263,7 +263,7 @@ class EcomDev_PHPUnit_Constraint_Layout_Block extends EcomDev_PHPUnit_Constraint ...@@ -263,7 +263,7 @@ class EcomDev_PHPUnit_Constraint_Layout_Block extends EcomDev_PHPUnit_Constraint
} }
$this->setActualValue($blockInfo['class']); $this->setActualValue($blockInfo['class']);
$actualReflection = EcomDev_Utils_Reflection::getRelflection($this->_actualValue); $actualReflection = EcomDev_Utils_Reflection::getReflection($this->_actualValue);
return $this->_actualValue === $this->_expectedValue return $this->_actualValue === $this->_expectedValue
|| $actualReflection->isSubclassOf($this->_expectedValue); || $actualReflection->isSubclassOf($this->_expectedValue);
} }
......
...@@ -31,6 +31,7 @@ class EcomDev_Utils_Reflection ...@@ -31,6 +31,7 @@ class EcomDev_Utils_Reflection
* @param string|object $object class name * @param string|object $object class name
* @param string $property * @param string $property
* @param mixed $value * @param mixed $value
* @throws RuntimeException
*/ */
public static function setRestrictedPropertyValue($object, $property, $value) public static function setRestrictedPropertyValue($object, $property, $value)
{ {
...@@ -38,7 +39,7 @@ class EcomDev_Utils_Reflection ...@@ -38,7 +39,7 @@ class EcomDev_Utils_Reflection
throw new RuntimeException('For setting of restricted properties via Reflection, PHP version should be 5.3.0 or later'); throw new RuntimeException('For setting of restricted properties via Reflection, PHP version should be 5.3.0 or later');
} }
$reflectionObject = self::getRelflection($object); $reflectionObject = self::getReflection($object);
$reflectionProperty = $reflectionObject->getProperty($property); $reflectionProperty = $reflectionObject->getProperty($property);
$reflectionProperty->setAccessible(true); $reflectionProperty->setAccessible(true);
$reflectionProperty->setValue((is_string($object) ? null : $object), $value); $reflectionProperty->setValue((is_string($object) ? null : $object), $value);
...@@ -49,6 +50,7 @@ class EcomDev_Utils_Reflection ...@@ -49,6 +50,7 @@ class EcomDev_Utils_Reflection
* *
* @param string|object $object class name * @param string|object $object class name
* @param array $properties * @param array $properties
* @throws RuntimeException
*/ */
public static function setRestrictedPropertyValues($object, array $properties) public static function setRestrictedPropertyValues($object, array $properties)
{ {
...@@ -67,6 +69,7 @@ class EcomDev_Utils_Reflection ...@@ -67,6 +69,7 @@ class EcomDev_Utils_Reflection
* @param string|object $object class name * @param string|object $object class name
* @param string $property * @param string $property
* @return mixed * @return mixed
* @throws RuntimeException
*/ */
public static function getRestrictedPropertyValue($object, $property) public static function getRestrictedPropertyValue($object, $property)
{ {
...@@ -74,7 +77,7 @@ class EcomDev_Utils_Reflection ...@@ -74,7 +77,7 @@ class EcomDev_Utils_Reflection
throw new RuntimeException('For getting of restricted properties via Reflection, PHP version should be 5.3.0 or later'); throw new RuntimeException('For getting of restricted properties via Reflection, PHP version should be 5.3.0 or later');
} }
$reflectionObject = self::getRelflection($object); $reflectionObject = self::getReflection($object);
$reflectionProperty = $reflectionObject->getProperty($property); $reflectionProperty = $reflectionObject->getProperty($property);
$reflectionProperty->setAccessible(true); $reflectionProperty->setAccessible(true);
return $reflectionProperty->getValue((is_string($object) ? null : $object)); return $reflectionProperty->getValue((is_string($object) ? null : $object));
...@@ -88,6 +91,7 @@ class EcomDev_Utils_Reflection ...@@ -88,6 +91,7 @@ class EcomDev_Utils_Reflection
* @param string $method * @param string $method
* @param array $args * @param array $args
* @return mixed * @return mixed
* @throws RuntimeException
*/ */
public static function invokeRestrictedMethod($object, $method, $args = array()) public static function invokeRestrictedMethod($object, $method, $args = array())
{ {
...@@ -95,7 +99,7 @@ class EcomDev_Utils_Reflection ...@@ -95,7 +99,7 @@ class EcomDev_Utils_Reflection
throw new RuntimeException('For invoking restricted methods via Reflection, PHP version should be 5.3.2 or later'); throw new RuntimeException('For invoking restricted methods via Reflection, PHP version should be 5.3.2 or later');
} }
$reflectionObject = self::getRelflection($object); $reflectionObject = self::getReflection($object);
$reflectionMethod = $reflectionObject->getMethod($method); $reflectionMethod = $reflectionObject->getMethod($method);
$reflectionMethod->setAccessible(true); $reflectionMethod->setAccessible(true);
...@@ -111,8 +115,21 @@ class EcomDev_Utils_Reflection ...@@ -111,8 +115,21 @@ class EcomDev_Utils_Reflection
* *
* @param string|object $object * @param string|object $object
* @return ReflectionClass|ReflectionObject * @return ReflectionClass|ReflectionObject
* @deprecated since 0.3.0 deprecated because of typo
*/ */
public static function getRelflection($object) public static function getRelflection($object)
{
return self::getReflection($object);
}
/**
* Returns reflection object from instance or class name
*
* @param string|object $object
* @return ReflectionClass|ReflectionObject
* @throws InvalidArgumentException
*/
public static function getReflection($object)
{ {
// If object is a class name // If object is a class name
if (is_string($object) && class_exists($object)) { if (is_string($object) && class_exists($object)) {
......
# EcomDev_PHPUnit definition # EcomDev_PHPUnit definition
UnitTests.php UnitTests.php
app/etc/modules/EcomDev_PHPUnit.xml app/etc/modules/EcomDev_PHPUnit.xml app/etc/modules/EcomDev_PHPUnit.xml app/etc/modules/EcomDev_PHPUnit.xml
app/code/community/EcomDev/PHPUnit app/code/community/EcomDev/PHPUnit app/code/community/EcomDev/PHPUnit app/code/community/EcomDev/PHPUnit
lib/EcomDev/PHPUnit lib/EcomDev/PHPUnit lib/EcomDev/PHPUnit lib/EcomDev/PHPUnit
...@@ -8,10 +7,5 @@ lib/Spyc lib/Spyc ...@@ -8,10 +7,5 @@ lib/Spyc lib/Spyc
lib/vfsStream lib/vfsStream lib/vfsStream lib/vfsStream
shell/ecomdev-phpunit-install.php shell/ecomdev-phpunit-install.php shell/ecomdev-phpunit-install.php shell/ecomdev-phpunit-install.php
# Copy local.xml.phpunit if it doesn't already exist # Run shell installer
@shell \ @shell cd $PROJECT/shell && php -f ecomdev-phpunit-install.php -- --module $MODULE --project $PROJECT
DIR_BEFORE_INSTALL=`pwd` \
cd $PROJECT/shell \
php -f ecomdev-phpunit-install.php --module $MODULE --project $PROJECT \
cd $DIR_BEFORE_INSTALL
...@@ -11,9 +11,13 @@ ...@@ -11,9 +11,13 @@
stopOnSkipped="false" stopOnSkipped="false"
strict="false" strict="false"
verbose="false" verbose="false"
bootstrap="app/code/community/EcomDev/PHPUnit/Test/bootstrap.php" bootstrap="app/code/community/EcomDev/PHPUnit/bootstrap.php">
loader="" <listeners>
> <listener file="app/code/community/EcomDev/PHPUnit/Test/Listener.php" class="EcomDev_PHPUnit_Test_Listener" />
</listeners>
<testsuite name="Magento Test Suite">
<file>app/code/community/EcomDev/PHPUnit/Test/Suite.php</file>
</testsuite>
<filter> <filter>
<blacklist> <blacklist>
<!-- Exclude Magento Core files from code coverage --> <!-- Exclude Magento Core files from code coverage -->
......
...@@ -48,6 +48,7 @@ class EcomDev_PHPUnit_Install extends Mage_Shell_Abstract ...@@ -48,6 +48,7 @@ class EcomDev_PHPUnit_Install extends Mage_Shell_Abstract
$this->_copyLocalXml(); $this->_copyLocalXml();
$this->_copyPHPUnitXml(); $this->_copyPHPUnitXml();
$this->_cleanCache();
} }
/** /**
...@@ -76,4 +77,23 @@ class EcomDev_PHPUnit_Install extends Mage_Shell_Abstract ...@@ -76,4 +77,23 @@ class EcomDev_PHPUnit_Install extends Mage_Shell_Abstract
$this->getArg('project') . DIRECTORY_SEPARATOR . self::FILE_PHPUNIT_XML); $this->getArg('project') . DIRECTORY_SEPARATOR . self::FILE_PHPUNIT_XML);
} }
} }
/**
* Clears cache of the magento project
*
*
*/
protected function _cleanCache()
{
if (is_dir($this->getArg('project') . '/var/cache')) {
shell_exec('rm -rf ' . $this->getArg('project') . '/var/cache');
}
if (is_dir($this->getArg('project') . '/var/phpunit.cache')) {
shell_exec('rm -rf ' . $this->getArg('project') . '/var/phpunit.cache');
}
}
} }
$shell = new EcomDev_PHPUnit_Install();
$shell->run();
\ No newline at end of file
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