Commit e9104eec authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

Merge branch 'release/0.3.5'

parents 1cd444fe 460f4a42
......@@ -372,7 +372,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
*
* @see Mage_Core_Controller_Request_Http::getBaseUrl()
*/
public function getBaseUrl()
public function getBaseUrl($raw = false)
{
return $this->_baseUrl;
}
......
......@@ -124,11 +124,11 @@ class EcomDev_PHPUnit_Model_Config extends Mage_Core_Model_Config
*/
public function getModelInstance($modelClass='', $constructArguments=array())
{
if (!isset($this->_replaceInstanceCreation['model'][$modelClass])) {
return parent::getModelInstance($modelClass, $constructArguments);
if (!isset($this->_replaceInstanceCreation['model'][(string)$modelClass])) {
return parent::getModelInstance((string)$modelClass, $constructArguments);
}
return $this->_replaceInstanceCreation['model'][$modelClass];
return $this->_replaceInstanceCreation['model'][(string)$modelClass];
}
/**
......
......@@ -301,7 +301,7 @@ class EcomDev_PHPUnit_Model_Fixture
public function loadByTestCase(PHPUnit_Framework_TestCase $testCase)
{
$fixtures = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
get_class($testCase), 'loadFixture', array('class', 'method'), $testCase->getName(false)
get_class($testCase), 'loadFixture', array('method', 'class'), $testCase->getName(false)
);
$this->_loadFixtureFiles($fixtures, $testCase);
......@@ -412,7 +412,7 @@ class EcomDev_PHPUnit_Model_Fixture
if (empty($this->_fixture)) {
$this->_fixture = $data;
} else {
$this->_fixture = array_merge_recursive($this->_fixture, $data);
$this->_fixture = array_replace_recursive($this->_fixture, $data);
}
return $this;
......
......@@ -139,6 +139,19 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Config
{
Mage::getConfig()->loadScopeSnapshot();
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;
}
......@@ -160,6 +173,16 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Config
$value = $backend->getValue();
}
if (is_array($value)) {
Mage::throwException(
sprintf(
'There is a collision in configuration value %s. Got: %s',
$path,
print_r($value, true)
)
);
}
Mage::getConfig()->setNode($path, $value);
return $this;
}
......
......@@ -89,10 +89,15 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Eav
$this->getResource()->beginTransaction();
foreach ($data as $entityType => $values) {
$eavLoaders[] = $this->_getEavLoader($entityType)
$eavLoaders[$entityType] = $this->_getEavLoader($entityType)
->setFixture($fixture)
->setOptions($fixture->getOptions())
->loadEntity($entityType, $values);
->setOptions($fixture->getOptions());
if ($eavLoaders[$entityType] instanceof EcomDev_PHPUnit_Model_Mysql4_Fixture_RestoreAwareInterface) {
$eavLoaders[$entityType]->saveData($entityType);
}
$eavLoaders[$entityType]->loadEntity($entityType, $values);
}
$this->getResource()->commit();
......@@ -126,16 +131,35 @@ class EcomDev_PHPUnit_Model_Fixture_Processor_Eav
EcomDev_PHPUnit_Model_FixtureInterface::SCOPE_SHARED);
}
$typesToRestore = array();
$this->getResource()->beginTransaction();
foreach (array_keys($data) as $entityType) {
$eavLoader = $this->_getEavLoader($entityType);
if (in_array($entityType, $ignoreCleanUp)) {
if ($eavLoader instanceof EcomDev_PHPUnit_Model_Mysql4_Fixture_RestoreAwareInterface) {
$eavLoader->clearData($entityType);
}
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();
}
return $this;
}
}
\ No newline at end of file
......@@ -22,7 +22,10 @@
*/
abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
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
*
......@@ -37,6 +40,20 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
*/
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
*
......@@ -99,6 +116,69 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
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
*
......@@ -112,7 +192,7 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
$this->_originalIndexers = $this->_requiredIndexers;
if (!empty($this->_options['addRequiredIndex'])) {
foreach ($this->_options['addRequiredIndex'] as $data) {
if (preg_match('/^([a-z0-9_\\-])+\\s+([a-z0-9_\\-])\s*$/i', $data, $match)
if (preg_match('/^([a-z0-9_\\-]+)\\s+([a-z0-9_\\-]+)\s*$/i', $data, $match)
&& $match[1] == $entityType) {
$this->_requiredIndexers[] = $match[2];
}
......@@ -140,15 +220,42 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_AbstractEav
// See getCustomTableRecords
$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)])) {
throw new RuntimeException('Entity Id should be specified in EAV fixture');
}
// 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'])) {
$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
......
......@@ -23,10 +23,37 @@
*/
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(
'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
* (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
......@@ -43,10 +43,19 @@ class EcomDev_PHPUnit_Test_Case_Helper_Session
*/
public function helperMockSession($classAlias, array $methods = array())
{
if (!empty($methods) && !in_array('start', $methods, true)) {
$methods[] = 'start';
}
$sessionMock = EcomDev_PHPUnit_Helper::invoke('mockModel', $classAlias, $methods)
->disableOriginalConstructor();
TestUtil::replaceByMock('singleton', $classAlias, $sessionMock);
$sessionMock->expects($this->testCase->any())
->method('start')
->willReturnSelf();
return $sessionMock;
}
......@@ -58,6 +67,8 @@ class EcomDev_PHPUnit_Test_Case_Helper_Session
*/
public function helperAdminSession(array $resources = array())
{
$this->helperMockSession('core/session', array('renew'));
$this->helperMockSession('adminhtml/session', array('renew'));
$session = $this->helperMockSession('admin/session', array('refreshAcl'));
$user = $this->createUser();
$this->loadRules($user, $this->getAcl(), $resources);
......
......@@ -50,6 +50,8 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
$suite = new self('Magento Test Suite');
$excludedModules = Mage::getConfig()->getNode('phpunit/suite/exclude');
// Walk through different groups in modules for finding test cases
foreach ($groups->children() as $group) {
foreach ($modules->children() as $module) {
......@@ -59,6 +61,10 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
continue;
}
if (isset($excludedModules->{$module->getName()})) {
continue;
}
$moduleCodeDir = Mage::getBaseDir('code') . DS . (string) $realModule->codePool;
$searchPath = Mage::getModuleDir('', $module->getName()) . DS . 'Test' . DS . (string) $group;
......
......@@ -68,9 +68,18 @@ class EcomDev_PHPUnit_Test_Suite_Group extends PHPUnit_Framework_TestSuite
* impossibility for specifying group by parent test case
* Because it is a very dirty hack :(
**/
$testGroups = array();
$testGroups = EcomDev_Utils_Reflection::getRestrictedPropertyValue($test, 'groups');
foreach ($groups as $group) {
if(!isset($testGroups[$group])) {
$testGroups[$group] = $test->tests();
} else {
foreach($test->tests() as $subTest) {
if(!in_array($subTest, $testGroups[$group], true)) {
$testGroups[$group][] = $subTest;
}
}
}
}
EcomDev_Utils_Reflection::setRestrictedPropertyValue(
......
......@@ -55,6 +55,8 @@
</global>
<phpunit>
<suite>
<modules /> <!-- List of modules included into test suite -->
<exclude /> <!-- List of modules that are excluded from test suite -->
<yaml>
<model>ecomdev_phpunit/yaml_loader</model>
<loaders>
......@@ -112,6 +114,37 @@
<catalog_product>ecomdev_phpunit/fixture_eav_catalog_product</catalog_product>
<catalog_category>ecomdev_phpunit/fixture_eav_catalog_category</catalog_category>
</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>
<app>
<!-- Application class name for running tests -->
......
<?php
/**
* @loadSharedFixture testFixtureArrayMerge.yaml
*/
class EcomDev_PHPUnitTest_Test_Model_Fixture extends EcomDev_PHPUnit_Test_Case
{
public function testFixtureArrayMerge()
{
require_once($this->_getVfsUrl('app/code/community/EcomDev/PHPUnit/Test/Model/ExampleClass.php'));
$testCase = new EcomDev_PHPUnitTest_Test_Model_ExampleClass();
$testCase->setName('testLoadFixtureOrder');
$this->getFixture()->loadForClass(get_class($testCase));
$this->getFixture()->loadByTestCase($testCase);
$this->getFixture()->apply();
}
public function testLoadClassBeforeMethodFixtures()
{
require_once($this->_getVfsUrl('app/code/community/EcomDev/PHPUnit/Test/Model/ExampleClass.php'));
$testCase = new EcomDev_PHPUnitTest_Test_Model_ExampleClass();
$testCase->setName('testLoadFixtureOrder');
$this->getFixture()->loadForClass(get_class($testCase));
$this->getFixture()->loadByTestCase($testCase);
$this->getFixture()->apply();
$this->assertEquals('methodFixtureValue', Mage::getStoreConfig('sample/path'));
}
protected function _getVfsUrl($path)
{
return $this->getFixture()->getVfs()->url($path);
}
}
vfs:
app:
code:
community:
EcomDev:
PHPUnit:
Test:
Model:
ExampleClass.php: |
<?php
/**
* @loadSharedFixture sharedClassFixture.yaml
* @loadFixture classFixture.yaml
*/
class EcomDev_PHPUnitTest_Test_Model_ExampleClass extends EcomDev_PHPUnit_Test_Case
{
/**
* @loadSharedFixture sharedMethodFixture.yaml
* @loadFixture methodFixture.yaml
*/
public function testLoadFixtureOrder()
{
}
}
fixtures:
classFixture.yaml: >
config:
default/sample/path: classFixtureValue
sharedClassFixture.yaml: >
config:
default/sample/path: sharedClassFixtureValue
sharedMethodFixture.yaml: >
config:
default/sample/path: sharedMethodFixtureValue
methodFixture.yaml: >
config:
default/sample/path: methodFixtureValue
......@@ -8,6 +8,9 @@
"magento-hackathon/magento-composer-installer": "*",
"phpunit/phpunit": "4.1.*"
},
"replace": {
"ivanchepurnyi/ecomdev_phpunit":"*"
},
"authors":[
{
"name":"Ivan Chepurnyi"
......
......@@ -292,7 +292,7 @@ class EcomDev_PHPUnit_Constraint_Layout_Block extends EcomDev_PHPUnit_Constraint
return false;
}
return $blockInfo['root'] === true;
return $blockInfo['is_root'] === true;
}
/**
......
......@@ -81,7 +81,7 @@ class EcomDev_PHPUnit_Constraint_Layout_Block_Property
* (non-PHPdoc)
* @see EcomDev_PHPUnit_ConstraintAbstract::getActualValue()
*/
protected function getActualValue($other)
protected function getActualValue($other = null)
{
if ($this->_useActualValue) {
if ($this->_actualValue instanceof Varien_Object) {
......
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