Commit 01d53b80 authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

Merge branch 'release/0.3.7'

parents decb1d48 cdc21297
...@@ -89,10 +89,15 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Eav ...@@ -89,10 +89,15 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Eav
$this->getResource()->beginTransaction(); $this->getResource()->beginTransaction();
foreach ($data as $entityType => $values) { foreach ($data as $entityType => $values) {
$eavLoaders[] = $this->_getEavLoader($entityType) $eavLoaders[$entityType] = $this->_getEavLoader($entityType)
->setFixture($fixture) ->setFixture($fixture)
->setOptions($fixture->getOptions()) ->setOptions($fixture->getOptions());
->loadEntity($entityType, $values);
if ($eavLoaders[$entityType] instanceof EcomDev_PHPUnit_Model_Mysql4_Fixture_RestoreAwareInterface) {
$eavLoaders[$entityType]->saveData($entityType);
}
$eavLoaders[$entityType]->loadEntity($entityType, $values);
} }
$this->getResource()->commit(); $this->getResource()->commit();
...@@ -126,16 +131,35 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Eav ...@@ -126,16 +131,35 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Eav
EcomDev_PHPUnit_Model_FixtureInterface::SCOPE_SHARED); EcomDev_PHPUnit_Model_FixtureInterface::SCOPE_SHARED);
} }
$typesToRestore = array();
$this->getResource()->beginTransaction(); $this->getResource()->beginTransaction();
foreach (array_keys($data) as $entityType) { foreach (array_keys($data) as $entityType) {
$eavLoader = $this->_getEavLoader($entityType);
if (in_array($entityType, $ignoreCleanUp)) { if (in_array($entityType, $ignoreCleanUp)) {
if ($eavLoader instanceof EcomDev_PHPUnit_Model_Mysql4_Fixture_RestoreAwareInterface) {
$eavLoader->clearData($entityType);
}
continue; continue;
} }
$this->_getEavLoader($entityType)
->cleanEntity($entityType); $eavLoader->cleanEntity($entityType);
if ($eavLoader instanceof EcomDev_PHPUnit_Model_Mysql4_Fixture_RestoreAwareInterface) {
$typesToRestore[$entityType] = $eavLoader;
} }
}
$this->getResource()->commit();
if ($typesToRestore) {
$this->getResource()->beginTransaction();
foreach ($typesToRestore as $entityType => $eavLoader) {
$eavLoader->restoreData($entityType)
->clearData($entityType);
}
$this->getResource()->commit(); $this->getResource()->commit();
}
return $this; return $this;
} }
} }
\ No newline at end of file
...@@ -22,7 +22,10 @@ ...@@ -22,7 +22,10 @@
*/ */
abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
extends EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractComplex extends EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractComplex
implements EcomDev_PHPUnit_Model_Mysql4_Fixture_RestoreAwareInterface
{ {
const RESTORE_KEY = 'restore_%s_data';
/** /**
* List of indexers required to build * List of indexers required to build
* *
...@@ -37,6 +40,20 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav ...@@ -37,6 +40,20 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
*/ */
protected $_originalIndexers = array(); protected $_originalIndexers = array();
/**
* List of tables that should be restored after run
*
* @var string[]
*/
protected $_restoreTables = array();
/**
* Default data for eav entity
*
* @var array
*/
protected $_defaultData = array();
/** /**
* Retrieve required indexers for re-building * Retrieve required indexers for re-building
* *
...@@ -99,6 +116,69 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav ...@@ -99,6 +116,69 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
return $this; return $this;
} }
/**
* Saves data for restoring it after fixture has been cleaned up
*
* @param string $code storage code
* @return $this
*/
public function saveData($code)
{
if ($this->_restoreTables) {
$storageKey = sprintf(self::RESTORE_KEY, $code);
$data = array();
foreach ($this->_restoreTables as $table) {
$select = $this->_getReadAdapter()->select();
$select->from($table);
$data[$table] = $this->_getReadAdapter()->fetchAll($select);
}
$this->_fixture->setStorageData($storageKey, $data);
}
return $this;
}
/**
* Restored saved data
*
* @param string $code storage code
* @return $this
*/
public function restoreData($code)
{
if ($this->_restoreTables) {
$storageKey = sprintf(self::RESTORE_KEY, $code);
$data = $this->_fixture->getStorageData($storageKey);
foreach ($this->_restoreTables as $table) {
if (!empty($data[$table])) {
$this->_getWriteAdapter()->insertOnDuplicate(
$table,
$data[$table]
);
}
}
}
return $this;
}
/**
* Clears storage from stored backup data
*
* @param $code
* @return $this
*/
public function clearData($code)
{
if ($this->_restoreTables) {
$storageKey = sprintf(self::RESTORE_KEY, $code);
$this->_fixture->setStorageData($storageKey, array());
}
return $this;
}
/** /**
* Loads EAV data into DB tables * Loads EAV data into DB tables
* *
...@@ -140,15 +220,42 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav ...@@ -140,15 +220,42 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
// See getCustomTableRecords // See getCustomTableRecords
$customValues = array(); $customValues = array();
foreach ($values as $index => &$row) { if ($this->_defaultData) {
$dataToInsert = $this->_defaultData;
// Prevent insertion of default data,
// if there is already data available
foreach ($values as $index => $row) {
if (isset($row[$this->_getEntityIdField($entityTypeModel)])
&& isset($dataToInsert[$this->_getEntityIdField($entityTypeModel)])) {
$dataToInsert = array();
break;
}
}
foreach ($dataToInsert as $row) {
array_unshift($values, $row);
}
}
foreach ($values as $index => $row) {
if (!isset($row[$this->_getEntityIdField($entityTypeModel)])) { if (!isset($row[$this->_getEntityIdField($entityTypeModel)])) {
throw new RuntimeException('Entity Id should be specified in EAV fixture'); throw new RuntimeException('Entity Id should be specified in EAV fixture');
} }
// Fulfill necessary information // Fulfill necessary information
$row['entity_type_id'] = $entityTypeModel->getEntityTypeId(); $values[$index]['entity_type_id'] = $entityTypeModel->getEntityTypeId();
$row = $values[$index];
if (!isset($row['attribute_set_id'])) { if (!isset($row['attribute_set_id'])) {
$row['attribute_set_id'] = $entityTypeModel->getDefaultAttributeSetId(); $defaultAttributeSet = $entityTypeModel->getDefaultAttributeSetId();
// Fix Magento core issue with attribute set information for customer and its address
if (in_array($entityType, array('customer', 'customer_address'))) {
$defaultAttributeSet = 0;
}
$values[$index]['attribute_set_id'] = $defaultAttributeSet;
} }
// Preparing entity table record // Preparing entity table record
......
...@@ -23,10 +23,37 @@ ...@@ -23,10 +23,37 @@
*/ */
class EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Catalog_Category extends EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Catalog_Abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Catalog_Category extends EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Catalog_Abstract
{ {
const XML_PATH_DEFAULT_DATA = 'phpunit/suite/fixture/default_data/category';
protected $_requiredIndexers = array( protected $_requiredIndexers = array(
'catalog_category_flat' 'catalog_category_flat'
); );
protected function _construct()
{
parent::_construct();
$defaultData = Mage::getConfig()->getNode(self::XML_PATH_DEFAULT_DATA);
if ($defaultData) {
foreach ($defaultData->children() as $item) {
if (!isset($item->entity_id)) {
continue;
}
$entityId = (string)$item->entity_id;
$this->_defaultData[$entityId] = array();
foreach ($item->children() as $value) {
$this->_defaultData[$entityId][$value->getName()] = (string)$value;
}
}
}
$this->_restoreTables[] = $this->getTable('catalog/category');
foreach (array('datetime', 'decimal', 'int', 'text', 'varchar') as $suffix) {
$this->_restoreTables[] = $this->getTable(array('catalog/category', $suffix));
}
}
/** /**
* Overridden to add easy fixture loading for product associations * Overridden to add easy fixture loading for product associations
* (non-PHPdoc) * (non-PHPdoc)
......
<?php
interface EcomDev_PHPUnit_Model_Mysql4_Fixture_RestoreAwareInterface
{
/**
* Saves data for restoring it after fixture has been cleaned up
*
* @param string $code storage code
* @return $this
*/
public function saveData($code);
/**
* Restored saved data
*
* @param string $code storage code
* @return $this
*/
public function restoreData($code);
/**
* Clears storage from stored backup data
*
* @param $code
* @return $this
*/
public function clearData($code);
}
\ No newline at end of file
...@@ -24,6 +24,7 @@ use EcomDev_PHPUnit_Helper as TestHelper; ...@@ -24,6 +24,7 @@ use EcomDev_PHPUnit_Helper as TestHelper;
* *
* @method EcomDev_PHPUnit_Mock_Proxy mockClassAlias(string $type, $classAlias, array $methods = array(), array $constructorArgs = array()) * @method EcomDev_PHPUnit_Mock_Proxy mockClassAlias(string $type, $classAlias, array $methods = array(), array $constructorArgs = array())
* @method EcomDev_PHPUnit_Mock_Proxy mockModel($classAlias, array $methods = array(), array $constructorArgs = array()) * @method EcomDev_PHPUnit_Mock_Proxy mockModel($classAlias, array $methods = array(), array $constructorArgs = array())
* @method EcomDev_PHPUnit_Mock_Proxy mockResourceModel($classAlias, array $methods = array(), array $constructorArgs = array())
* @method EcomDev_PHPUnit_Mock_Proxy mockBlock($classAlias, array $methods = array(), array $constructorArgs = array()) * @method EcomDev_PHPUnit_Mock_Proxy mockBlock($classAlias, array $methods = array(), array $constructorArgs = array())
* @method EcomDev_PHPUnit_Mock_Proxy mockHelper($classAlias, array $methods = array(), array $constructorArgs = array()) * @method EcomDev_PHPUnit_Mock_Proxy mockHelper($classAlias, array $methods = array(), array $constructorArgs = array())
* @method EcomDev_PHPUnit_Mock_Proxy mockSession($classAlias, array $methods = array()) * @method EcomDev_PHPUnit_Mock_Proxy mockSession($classAlias, array $methods = array())
......
...@@ -55,6 +55,21 @@ class EcomDev_PHPUnit_Test_Case_Helper_Mock extends EcomDev_PHPUnit_AbstractHelp ...@@ -55,6 +55,21 @@ class EcomDev_PHPUnit_Test_Case_Helper_Mock extends EcomDev_PHPUnit_AbstractHelp
return $this->helperMockClassAlias('model', $classAlias, $methods, $constructorArgs); return $this->helperMockClassAlias('model', $classAlias, $methods, $constructorArgs);
} }
/**
* Creates a mock for a resource model by its class alias
*
* @param string $classAlias
* @param array $methods
* @param array $constructorArgs
*
* @return EcomDev_PHPUnit_Mock_Proxy
*/
public function helperMockResourceModel($classAlias, array $methods = array(), array $constructorArgs = array())
{
return $this->helperMockClassAlias('resource_model', $classAlias, $methods, $constructorArgs);
}
/** /**
* Creates a mock for a block by its class alias * Creates a mock for a block by its class alias
* *
......
...@@ -501,7 +501,7 @@ class EcomDev_PHPUnit_Test_Case_Util ...@@ -501,7 +501,7 @@ class EcomDev_PHPUnit_Test_Case_Util
public static function getGroupedClassMockBuilder(PHPUnit_Framework_TestCase $testCase, $type, $classAlias) public static function getGroupedClassMockBuilder(PHPUnit_Framework_TestCase $testCase, $type, $classAlias)
{ {
$className = self::getGroupedClassName($type, $classAlias); $className = self::getGroupedClassName($type, $classAlias);
return new EcomDev_PHPUnit_Mock_Proxy($testCase, $className); return new EcomDev_PHPUnit_Mock_Proxy($testCase, $className, $classAlias);
} }
/** /**
...@@ -511,6 +511,7 @@ class EcomDev_PHPUnit_Test_Case_Util ...@@ -511,6 +511,7 @@ class EcomDev_PHPUnit_Test_Case_Util
public static function setUp() public static function setUp()
{ {
self::app()->resetDispatchedEvents(); self::app()->resetDispatchedEvents();
self::$originalStore = Mage::app()->getStore()->getCode();
} }
/** /**
......
...@@ -173,6 +173,9 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -173,6 +173,9 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
)); ));
if ($test instanceof PHPUnit_Framework_TestCase) { if ($test instanceof PHPUnit_Framework_TestCase) {
EcomDev_PHPUnit_Helper::tearDown();
EcomDev_PHPUnit_Test_Case_Util::tearDown();
EcomDev_PHPUnit_Test_Case_Util::getFixture(get_class($test)) EcomDev_PHPUnit_Test_Case_Util::getFixture(get_class($test))
->setScope(EcomDev_PHPUnit_Model_FixtureInterface::SCOPE_LOCAL) ->setScope(EcomDev_PHPUnit_Model_FixtureInterface::SCOPE_LOCAL)
->discard(); // Clear applied fixture ->discard(); // Clear applied fixture
...@@ -180,9 +183,6 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener ...@@ -180,9 +183,6 @@ class EcomDev_PHPUnit_Test_Listener implements PHPUnit_Framework_TestListener
if (EcomDev_PHPUnit_Test_Case_Util::getExpectation(get_class($test))->isLoaded()) { if (EcomDev_PHPUnit_Test_Case_Util::getExpectation(get_class($test))->isLoaded()) {
EcomDev_PHPUnit_Test_Case_Util::getExpectation(get_class($test))->discard(); EcomDev_PHPUnit_Test_Case_Util::getExpectation(get_class($test))->discard();
} }
EcomDev_PHPUnit_Test_Case_Util::tearDown();
EcomDev_PHPUnit_Helper::tearDown();
} }
Mage::dispatchEvent('phpunit_test_end_after', array( Mage::dispatchEvent('phpunit_test_end_after', array(
......
...@@ -114,6 +114,37 @@ ...@@ -114,6 +114,37 @@
<catalog_product>ecomdev_phpunit/fixture_eav_catalog_product</catalog_product> <catalog_product>ecomdev_phpunit/fixture_eav_catalog_product</catalog_product>
<catalog_category>ecomdev_phpunit/fixture_eav_catalog_category</catalog_category> <catalog_category>ecomdev_phpunit/fixture_eav_catalog_category</catalog_category>
</eav> </eav>
<default_data>
<category>
<root>
<entity_id>1</entity_id>
<parent_id>0</parent_id>
<path>1</path>
<position>0</position>
<level>0</level>
<children_count>1</children_count>
<name>Root Catalog</name>
<url_key>root-catalog</url_key>
<is_active>1</is_active>
<is_anchor>0</is_anchor>
<attribute_set_id>0</attribute_set_id>
</root>
<default_category>
<entity_id>2</entity_id>
<parent_id>1</parent_id>
<path>1/2</path>
<position>1</position>
<level>1</level>
<children_count>0</children_count>
<name>Default Category</name>
<url_key>default-category</url_key>
<is_active>1</is_active>
<is_anchor>0</is_anchor>
<display_mode>PRODUCTS</display_mode>
<include_in_menu>1</include_in_menu>
</default_category>
</category>
</default_data>
</fixture> </fixture>
<app> <app>
<!-- Application class name for running tests --> <!-- Application class name for running tests -->
......
...@@ -29,6 +29,26 @@ class EcomDev_PHPUnit_Mock_Proxy ...@@ -29,6 +29,26 @@ class EcomDev_PHPUnit_Mock_Proxy
{ {
protected $mockInstance; protected $mockInstance;
/**
* Original mocked class alias
*
* @var string
*/
protected $classAlias;
/**
* Added class alias as property
*
* @param PHPUnit_Framework_TestCase $testCase
* @param array|string $type
* @param null $classAlias
*/
public function __construct(PHPUnit_Framework_TestCase $testCase, $type, $classAlias = null)
{
parent::__construct($testCase, $type);
$this->classAlias = $classAlias;
}
/** /**
* Adds method name to a mock builder * Adds method name to a mock builder
* *
...@@ -113,6 +133,18 @@ class EcomDev_PHPUnit_Mock_Proxy ...@@ -113,6 +133,18 @@ class EcomDev_PHPUnit_Mock_Proxy
return $this->getMockInstance()->expects($matcher); return $this->getMockInstance()->expects($matcher);
} }
/**
* Invokes replaceByMock test util method with current mock object proxy instance
*
* @param $type
* @return $this
*/
public function replaceByMock($type)
{
EcomDev_PHPUnit_Test_Case_Util::replaceByMock($type, $this->classAlias, $this);
return $this;
}
/** /**
* Returns invocation mocker for * Returns invocation mocker for
* *
......
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