Commit 83c456bc authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

Merge branch 'release/0.3.0'

parents 04d37272 181305ac
......@@ -8,8 +8,8 @@ This extension was created especially for resolving this problem and promoting t
System Requirements
-------------------
* PHP 5.3 or higher
* PHPUnit 3.6.x
* Magento CE1.4.x-1.5.x/PE1.9.x-PE1.10.x/EE1.9.x-1.10.x
* PHPUnit 3.7.x
* Magento CE1.4.x-1.7.x/PE1.9.x-PE1.10.x/EE1.9.x-1.12.x
Documentation
-------------
......@@ -40,31 +40,11 @@ required for proper controller tests.
4. Run the unit tests first time for installing test database. It will take about 3 minutes.
$ phpunit UnitTests.php
$ phpunit
5. If it shows that there was no tests found, it means that extension was successfully
installed. If it shows some errors than it means that your customizations has install
scripts that relay on your current database data so you should fix them.
### Magento Connect
1. Get the extension key from the [extension page](http://www.magentocommerce.com/magento-connect/EcomDev/extension/5717/ecomdev_phpunit) and install it via Magento Connect manager.
2. Open app/etc/local.xml.phpunit in editor that you are comfortable with:
1. Specify database credentials that will be used for test suite in
**global/resources/default_setup/connection** node
2. Specify **base_url** for **secure** and **unsecure** requests in **default/web** node. It is
required for proper controller tests.
3. Run the unit tests first time for installing test database. It will take about 3 minutes.
$ phpunit UnitTests.php
4. If it shows that there was no tests found, it means that extension was successfully
installed. If it shows some errors than it means that your customizations has install
scripts that relay on your current database data so you should fix them.
Issue Tracker
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -76,7 +76,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
*
* @param string|array $name
* @param string|null $value
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setCookie($name, $value)
{
......@@ -88,7 +88,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
* Sets more than one cookie
*
* @param array $cookies
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setCookies(array $cookies)
{
......@@ -99,7 +99,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets all cookies for the test request
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function resetCookies()
{
......@@ -110,7 +110,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets query for the current request
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function resetQuery()
{
......@@ -121,7 +121,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets $_POST superglobal for test request
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function resetPost()
{
......@@ -132,7 +132,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets user defined request params for test request
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function resetParams()
{
......@@ -143,7 +143,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets internal properties to its default values
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function resetInternalProperties()
{
......@@ -178,12 +178,24 @@ class EcomDev_PHPUnit_Controller_Request_Http
return $this;
}
/**
* Sets rawBody property to request
*
* @param string $rawBody
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setRawBody($rawBody)
{
$this->_rawBody = $rawBody;
return $this;
}
/**
* Set custom http header
*
* @param string $name
* @param string $value
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setHeader($name, $value)
{
......@@ -199,7 +211,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
* headers list is an associative array
*
* @param array $headers
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setHeaders(array $headers)
{
......@@ -229,7 +241,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets headers in test request
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function resetHeaders()
{
......@@ -255,7 +267,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
*
* @param string $name
* @param string $value
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setServer($name, $value)
{
......@@ -272,7 +284,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
* Sets multiple values for $_SERVER superglobal in test request
*
* @param array $values
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setServers(array $values)
{
......@@ -285,7 +297,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets $_SERVER superglobal to previous state
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function resetServer()
{
......@@ -307,7 +319,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
* Sets request method for test request
*
* @param string $requestMethod
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setMethod($requestMethod)
{
......@@ -320,7 +332,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
* accepts boolean flag for HTTPS
*
* @param boolean $flag
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function setIsSecure($flag = true)
{
......@@ -365,7 +377,7 @@ class EcomDev_PHPUnit_Controller_Request_Http
/**
* Resets all request data for test
*
* @return EcomDev_PHPUnit_Controller_Request_Http_Test
* @return EcomDev_PHPUnit_Controller_Request_Http
*/
public function reset()
{
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -131,6 +131,7 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
* List of module names stored by class name
*
* @var array
* @deprecated since 0.3.0
*/
protected $_moduleNameByClassName = array();
......@@ -402,7 +403,7 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
{
$className = (string)$this->getConfig()->getNode($configPath);
$reflection = EcomDev_Utils_Reflection::getRelflection($className);
$reflection = EcomDev_Utils_Reflection::getReflection($className);
if ($interface !== null && !$reflection->implementsInterface($interface)) {
throw new RuntimeException(
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
* @param string|object $className
* @throws RuntimeException if module name was not found for the passed class name
* @return string
* @deprecated since 0.3.0
*/
public function getModuleNameByClassName($className)
{
if (is_object($className)) {
$className = get_class($className);
}
if (!isset($this->_moduleNameByClassName[$className])) {
// Try to find the module name by class name
$moduleName = false;
foreach ($this->getConfig()->getNode('modules')->children() as $module) {
if (strpos($className, $module->getName()) === 0) {
$moduleName = $module->getName();
break;
}
}
if (!$moduleName) {
throw new RuntimeException('Cannot to find the module name for class name: ' . $className);
}
$this->setModuleNameForClassName($className, $moduleName);
}
return $this->_moduleNameByClassName[$className];
return EcomDev_PHPUnit_Test_Case_Util::getModuleNameByClassName($className);
}
/**
......@@ -478,10 +459,11 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
* @param string $className
* @param string $moduleName
* @return EcomDev_PHPUnit_Model_App
* @deprecated since 0.3.0
*/
public function setModuleNameForClassName($className, $moduleName)
{
$this->_moduleNameByClassName[$className] = $moduleName;
EcomDev_PHPUnit_Test_Case_Util::setModuleNameForClassName($className, $moduleName);
return $this;
}
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
<?php
// Loading Spyc yaml parser,
// becuase Symfony component is not working propertly with nested
require_once 'Spyc/spyc.php';
class EcomDev_PHPUnit_Model_Expectation
implements EcomDev_PHPUnit_Model_Expectation_Interface
{
......@@ -122,22 +118,27 @@ class EcomDev_PHPUnit_Model_Expectation
*
* @see EcomDev_PHPUnit_Model_Test_Loadable_Interface::loadByTestCase()
*/
public function loadByTestCase(EcomDev_PHPUnit_Test_Case $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) {
$expectations[] = null;
$expectations[] = $testCase->getName(false);
}
$expectationData = array();
foreach ($expectations as $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) {
$text = 'There was no expectation defined for current test case';
......@@ -148,7 +149,7 @@ class EcomDev_PHPUnit_Model_Expectation
}
$expectationData = array_merge_recursive(
$expectationData, Spyc::YAMLLoad($expectationFile)
$expectationData, EcomDev_PHPUnit_Test_Case_Util::getYamlLoader()->load($expectationFile)
);
}
......
......@@ -12,7 +12,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,14 +11,11 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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';
/**
* Fixture model for Magento unit tests
......@@ -27,44 +24,48 @@ require_once 'Spyc/spyc.php';
*
*/
class EcomDev_PHPUnit_Model_Fixture
extends Mage_Core_Model_Abstract
extends Varien_Object
implements EcomDev_PHPUnit_Model_Fixture_Interface
{
// 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';
// Configuration path for attribute loaders
const XML_PATH_FIXTURE_ATTRIBUTE_LOADERS = 'phpunit/suite/fixture/attribute';
// 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
const DEFAULT_SHARED_FIXTURE_NAME = 'default';
// Default eav loader class alias
const DEFAULT_EAV_LOADER_CLASS = 'ecomdev_phpunit/fixture_eav_default';
// Default attribute loader class alias
const DEFAULT_ATTRIBUTE_LOADER_CLASS = 'ecomdev_phpunit/fixture_attribute_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
const STORAGE_KEY_FIXTURE = 'fixture';
// 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
const STORAGE_KEY_ENTITIES = 'entities';
// Key for loaded attributes by attribute loaders
const STORAGE_KEY_ATTRIBUTES = 'attributes';
/* @deprecated since 0.3.0 */
const STORAGE_KEY_ENTITIES = EcomDev_PHPUnit_Model_Fixture_Processor_Eav::STORAGE_KEY;
// 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
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,
......@@ -119,16 +120,20 @@ class EcomDev_PHPUnit_Model_Fixture
*/
protected $_options = array();
/**
* Processors list
*
* @var EcomDev_PHPUnit_Model_Fixture_Processor_Interface[]
*/
protected $_processors = array();
/**
* List of scope model aliases by scope type
*
* @var array
* @deprecated since 0.3.0
*/
protected static $_scopeModelByType = array(
'store' => 'core/store',
'group' => 'core/store_group',
'website' => 'core/website'
);
protected static $_scopeModelByType = array();
/**
* Associative array of configuration nodes xml that was changed by fixture,
......@@ -148,16 +153,6 @@ class EcomDev_PHPUnit_Model_Fixture
protected $_currentScope = array();
/**
* Model constructor, just defines which resource model to use
* (non-PHPdoc)
* @see Varien_Object::_construct()
*/
protected function _construct()
{
$this->_init('ecomdev_phpunit/fixture');
}
/**
* Set fixture options
*
......@@ -170,6 +165,16 @@ class EcomDev_PHPUnit_Model_Fixture
return $this;
}
/**
* Retrieve fixture options
*
* @return array
*/
public function getOptions()
{
return $this->_options;
}
/**
* Sets storage for fixtures
*
......@@ -276,35 +281,28 @@ class EcomDev_PHPUnit_Model_Fixture
}
/**
* Check that current fixture scope is equal to SCOPE_DEFAULT
*
* @return boolean
*/
public function isScopeDefault()
{
return $this->getScope() === self::SCOPE_DEFAULT;
}
* Check that current fixture scope is equal to SCOPE_DEFAULT
*
* @return boolean
*/
public function isScopeDefault()
{
return $this->getScope() === self::SCOPE_DEFAULT;
}
/**
* Loads fixture files from test case annotations
*
* @param EcomDev_PHPUnit_Test_Case $testCase
* @return EcomDev_PHPUnit_Model_Fixture
* @param PHPUnit_Framework_TestCase $testCase
* @return PHPUnit_Framework_TestCase
*/
public function loadByTestCase(EcomDev_PHPUnit_Test_Case $testCase)
public function loadByTestCase(PHPUnit_Framework_TestCase $testCase)
{
$fixtures = $testCase->getAnnotationByName(
'loadFixture',
array('class', 'method')
$fixtures = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
get_class($testCase), 'loadFixture', array('class', 'method'), $testCase->getName(false)
);
$cacheOptions = $testCase->getAnnotationByName('cache', 'method');
$this->_parseCacheOptions($cacheOptions);
$this->_loadFixtureFiles($fixtures, $testCase);
return $this;
}
......@@ -316,24 +314,10 @@ class EcomDev_PHPUnit_Model_Fixture
*/
public function loadForClass($className)
{
$reflection = EcomDev_Utils_Reflection::getRelflection($className);
$method = $reflection->getMethod('getAnnotationByNameFromClass');
if (!$method instanceof ReflectionMethod) {
throw new RuntimeException('Unable to read class annotations, because it is not extended from EcomDev_PHPUnit_Test_Case');
}
$fixtures = $method->invokeArgs(
null, array($className, 'loadSharedFixture', 'class')
$fixtures = EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(
$className, 'loadSharedFixture', 'class'
);
$cacheOptions = $method->invokeArgs(
null, array($className, 'cache', 'class')
);
$this->_parseCacheOptions($cacheOptions);
$this->_loadFixtureFiles($fixtures, $className);
return $this;
}
......@@ -343,56 +327,64 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $annotations
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _parseCacheOptions($annotations)
{
$cacheOptions = array();
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;
}
return $this;
}
}
/**
* 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;
}
if ($cacheOptions) {
$this->_fixture['cache_options'] = $cacheOptions;
/**
* Returns value from fixture
*
* @param $key
* @return array[]
*/
public function getFixtureValue($key)
{
if (isset($this->_fixture[$key])) {
return $this->_fixture[$key];
}
return array();
}
/**
* Loads fixture files
*
* @param array $fixtures
* @param array $fixtures
* @param string|EcomDev_PHPUnit_Test_Case $classOrInstance
*
* @throws RuntimeException
* @return EcomDev_PHPUnit_Model_Fixture
*/
protected function _loadFixtureFiles(array $fixtures, $classOrInstance)
{
$isShared = ($this->isScopeShared() || !$classOrInstance instanceof EcomDev_PHPUnit_Test_Case);
$isShared = ($this->isScopeShared() || !$classOrInstance instanceof PHPUnit_Framework_TestCase);
foreach ($fixtures as $fixture) {
if (empty($fixture) && $isShared) {
$fixture = self::DEFAULT_SHARED_FIXTURE_NAME;
} elseif (empty($fixture)) {
$fixture = null;
$fixture = $classOrInstance->getName(false);
}
$filePath = false;
if ($isShared) {
$reflection = EcomDev_Utils_Reflection::getRelflection($classOrInstance);
$method = $reflection->getMethod('getYamlFilePathByClass');
if ($method instanceof ReflectionMethod) {
$filePath = $method->invokeArgs(null, array($classOrInstance, 'fixtures', $fixture));
}
} else {
$filePath = $classOrInstance->getYamlFilePath('fixtures', $fixture);
}
$className = (is_string($classOrInstance) ? $classOrInstance : get_class($classOrInstance));
$filePath = EcomDev_PHPUnit_Test_Case_Util::getYamlLoader()
->resolveFilePath($className, EcomDev_PHPUnit_Model_Yaml_Loader::TYPE_FIXTURE, $fixture);
if (!$filePath) {
throw new RuntimeException('Unable to load fixture for test');
......@@ -413,7 +405,7 @@ class EcomDev_PHPUnit_Model_Fixture
*/
public function loadYaml($filePath)
{
$data = Spyc::YAMLLoad($filePath);
$data = EcomDev_PHPUnit_Test_Case_Util::getYamlLoader()->load($filePath);
if (empty($this->_fixture)) {
$this->_fixture = $data;
......@@ -424,6 +416,26 @@ class EcomDev_PHPUnit_Model_Fixture
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
*
......@@ -431,13 +443,17 @@ class EcomDev_PHPUnit_Model_Fixture
*/
public function apply()
{
$processors = $this->getProcessors();
// Initialize fixture processors
foreach ($processors as $processor) {
$processor->initialize($this);
}
$this->setStorageData(self::STORAGE_KEY_FIXTURE, $this->_fixture);
$reflection = EcomDev_Utils_Reflection::getRelflection($this);
foreach ($this->_fixture as $part => $data) {
$method = '_apply' . uc_words($part, '', '_');
if ($reflection->hasMethod($method)) {
$this->$method($data);
if (isset($processors[$part])) {
$processors[$part]->apply($data, $part, $this);
}
}
......@@ -461,11 +477,11 @@ class EcomDev_PHPUnit_Model_Fixture
$this->_fixture = $fixture;
$this->setStorageData(self::STORAGE_KEY_FIXTURE, null);
$reflection = EcomDev_Utils_Reflection::getRelflection($this);
$processors = $this->getProcessors();
foreach ($this->_fixture as $part => $data) {
$method = '_discard' . uc_words($part, '', '_');
if ($reflection->hasMethod($method)) {
$this->$method($data);
if (isset($processors[$part])) {
$processors[$part]->discard($data, $part, $this);
}
}
......@@ -477,15 +493,10 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $options
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _applyCacheOptions($options)
{
$originalOptions = Mage::app()->getCacheOptions();
$this->setStorageData(self::STORAGE_KEY_CACHE_OPTIONS, $originalOptions);
$options += $originalOptions;
Mage::app()->setCacheOptions($options);
return $this;
}
......@@ -493,12 +504,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Discards changes that were made to Magento cache
*
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _discardCacheOptions()
{
Mage::app()->setCacheOptions(
$this->getStorageData(self::STORAGE_KEY_CACHE_OPTIONS)
);
return $this;
}
......@@ -507,33 +516,11 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $configuration
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
* @throws InvalidArgumentException in case if wrong configuration array supplied
*/
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;
}
......@@ -542,33 +529,11 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $configuration
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
* @throws InvalidArgumentException in case of wrong configuration data passed
*/
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;
}
......@@ -576,11 +541,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Restores config to a previous configuration scope
*
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _restoreConfig()
{
Mage::getConfig()->loadScopeSnapshot();
Mage::getConfig()->loadDb();
return $this;
}
......@@ -588,10 +552,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Reverts fixture configuration values in Mage_Core_Model_Config
*
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _discardConfig()
{
$this->_restoreConfig();
return $this;
}
......@@ -599,12 +563,10 @@ class EcomDev_PHPUnit_Model_Fixture
* Reverts fixture configuration xml values in Mage_Core_Model_Config
*
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _discardConfigXml()
{
if (!isset($this->_fixture['config'])) {
$this->_resetConfig();
}
return $this;
}
......@@ -613,34 +575,11 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $tables
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _applyTables($tables)
{
if (!is_array($tables)) {
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);
return $this;
}
/**
......@@ -648,33 +587,11 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $tables
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _discardTables($tables)
{
if (!is_array($tables)) {
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);
return $this;
}
/**
......@@ -683,27 +600,10 @@ class EcomDev_PHPUnit_Model_Fixture
* @param string $path
* @param string $value
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _setConfigNodeValue($path, $value)
{
$originalNode = Mage::getConfig()->getNode($path);
// Support for custom backend values
if (!empty($value) && $originalNode !== false && $originalNode->getAttribute('backend_model')) {
$backend = Mage::getModel((string) $originalNode->getAttribute('backend_model'));
$dataPath = explode('/', $path);
if (current($dataPath) === 'default') {
array_shift($dataPath);
} elseif (current($dataPath) === 'websites' || current($dataPath) === 'stores') {
$dataPath = array_splice($dataPath, 0, 2);
}
$backend->setPath(implode('/', $dataPath))->setValue($value);
EcomDev_Utils_Reflection::invokeRestrictedMethod($backend, '_beforeSave');
$value = $backend->getValue();
}
Mage::getConfig()->setNode($path, $value);
return $this;
}
......@@ -712,6 +612,7 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param string $entityType
* @return EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract
* @deprecated since 0.3.0
*/
protected function _getEavLoader($entityType)
{
......@@ -725,6 +626,7 @@ class EcomDev_PHPUnit_Model_Fixture
* @param string $entityType
* @param string $dataType
* @return EcomDev_PHPUnit_Model_Mysql4_Fixture
* @deprecated since 0.3.0
*/
protected function _getComplexLoader($entityType, $dataType)
{
......@@ -752,26 +654,10 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $entities
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
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;
}
......@@ -780,27 +666,10 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $entities
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
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;
}
......@@ -810,32 +679,10 @@ class EcomDev_PHPUnit_Model_Fixture
*
* @param array $types
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
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;
}
......@@ -845,66 +692,22 @@ class EcomDev_PHPUnit_Model_Fixture
* @param string $type
* @param array $row
* @return boolean|Mage_Core_Model_Abstract
* @deprecated since 0.3.0
*/
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;
}
$scopeModel = Mage::getModel(self::$_scopeModelByType[$type])->load($row[$type . '_id']);
$isNew = !$scopeModel->getId();
if ($isNew) {
// Change property for saving new objects with specified ids
EcomDev_Utils_Reflection::setRestrictedPropertyValues(
$scopeModel->getResource(),
array(
'_isPkAutoIncrement' => false
)
);
$scopeModel->isObjectNew(true);
}
$scopeModel->setData($row);
$scopeModel->save();
if ($isNew) {
// Revert changed property
EcomDev_Utils_Reflection::setRestrictedPropertyValues(
$scopeModel->getResource(),
array(
'_isPkAutoIncrement' => true
)
);
}
return $scopeModel;
}
return false;
}
/**
* Validate scope data
*
* @param array $types
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
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;
}
......@@ -913,133 +716,75 @@ class EcomDev_PHPUnit_Model_Fixture
* i.e., website, store, store group
*
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _discardScope()
{
if ($this->getStorageData(self::STORAGE_KEY_SCOPE) === null) {
return $this;
}
return $this;
}
Mage::app()->disableEvents();
$scope = array_reverse($this->getStorageData(self::STORAGE_KEY_SCOPE));
foreach ($scope as $models) {
foreach ($models as $model) {
$model->delete();
}
/**
* Returns VFS wrapper instance
*
* @return EcomDev_PHPUnit_Model_Fixture_Vfs
* @throws PHPUnit_Framework_SkippedTestError
*/
public function getVfs()
{
if ($this->_vfs !== null) {
return $this->_vfs;
}
$this->setStorageData(self::STORAGE_KEY_SCOPE, null);
if (is_dir(Mage::getBaseDir('lib') . DS . 'vfsStream' . DS . 'src')) {
spl_autoload_register(array($this, 'vfsAutoload'), true, true);
$this->_vfs = Mage::getModel('ecomdev_phpunit/fixture_vfs');
return $this->_vfs;
}
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
)
throw new PHPUnit_Framework_SkippedTestError(
'The test was skipped, since vfsStream component is not installed. '
. 'Try install submodules required for this functionality'
);
Mage::app()->enableEvents();
Mage::app()->reinitStores();
return $this;
}
/**
* Retrieves attribute loader for a particular entity type
*
* @param string $entityType
* @return EcomDev_PHPUnit_Model_Mysql4_Fixture_Attribute_Abstract
*/
protected function _getAttributeLoader($entityType)
{
return $this->_getComplexLoader($entityType, 'ATTRIBUTE');
}
/**
* Autoloader for vfs
*
* @param string $className
* @return bool
*/
public function vfsAutoload($className)
{
if (strpos($className, 'org\\bovigo\\vfs') === false) {
return false;
}
/**
* Applies fixture EAV attribute values
*/
protected function _applyAttributes($attributes)
{
if (!is_array($attributes)) {
throw new InvalidArgumentException(
'Attributes part should be an associative list with rows as value and attribute code as key'
);
}
if (!$this->getStorageData(self::STORAGE_KEY_ATTRIBUTES, self::SCOPE_DEFAULT)) {
// since attributes are being used, we need to load all previously-existing
// attributes into default scope
$ignoreCleanup = array();
foreach(array_keys($attributes) as $entityType) {
$ignoreCleanup[$entityType] = $this->_getAttributeLoader(self::DEFAULT_SHARED_FIXTURE_NAME)
->setFixture($this)
->setOptions($this->_options)
->loadDefaultAttributes($entityType);
}
$this->setStorageData(self::STORAGE_KEY_ATTRIBUTES, $ignoreCleanup, self::SCOPE_DEFAULT);
}
$this->getResource()->beginTransaction();
foreach ($attributes as $entityType => $values) {
$this->_getAttributeLoader($entityType)
->setFixture($this)
->setOptions($this->_options)
->loadAttribute($entityType, $values);
}
$this->getResource()->commit();
$this->setStorageData(self::STORAGE_KEY_ATTRIBUTES, $attributes);
return $this;
}
$fileName = 'vfsStream' . DS . 'src' . DS . 'main' . DS . 'php' . DS
. strtr(trim($className, '\\'), '\\', DS) . '.php';
/**
* Clean applied attribute data
*
* @param array $attributes
* @return EcomDev_PHPUnit_Model_Fixture
*/
protected function _discardAttributes($attributes)
{
// Ignore cleaning of attributes if they existed before fixtures were loaded
$ignoreCleanUp = $this->getStorageData(self::STORAGE_KEY_ATTRIBUTES, self::SCOPE_DEFAULT);
if($ignoreCleanUp === null) $ignoreCleanUp = array();
// Ignore cleaning of attributes if shared fixture loaded something for them
if ($this->isScopeLocal() && $this->getStorageData(self::STORAGE_KEY_ATTRIBUTES, self::SCOPE_SHARED)) {
$ignoreCleanUp = array_merge_recursive(
$ignoreCleanUp,
$this->getStorageData(self::STORAGE_KEY_ENTITIES, self::SCOPE_SHARED)
);
}
$this->getResource()->beginTransaction();
foreach ($attributes as $entityType => $values) {
$attributeCodes = array();
foreach ($values as $value) {
if (isset($value['attribute_code'])
&& !in_array($value['attribute_code'], $ignoreCleanUp[$entityType])) {
$attributeCodes[] = $value['attribute_code'];
}
}
if (!empty($attributeCodes)) {
$this->_getAttributeLoader(self::DEFAULT_SHARED_FIXTURE_NAME)
->cleanAttributes($entityType, $attributeCodes);
}
}
$this->getResource()->commit();
foreach (array_keys($attributes) as $entityType) {
$this->_getAttributeLoader(self::DEFAULT_SHARED_FIXTURE_NAME)->resetAttributesAutoIncrement($entityType);
}
$this->_getAttributeLoader(self::DEFAULT_SHARED_FIXTURE_NAME)->resetAttributesAutoIncrement();
return $this;
}
return include $fileName;
}
/**
* Applies VFS structure fixture
*
* @param array $data
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _applyVfs($data)
{
return $this;
}
/**
* Discards VFS structure fixture
*
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.3.0
*/
protected function _discardVfs()
{
return $this;
}
}
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -40,6 +40,13 @@ interface EcomDev_PHPUnit_Model_Fixture_Interface extends EcomDev_PHPUnit_Model_
*/
public function setOptions(array $options);
/**
* Sets fixture options
*
* @return array
*/
public function getOptions();
/**
* Sets storage for fixtures
*
......@@ -117,4 +124,30 @@ interface EcomDev_PHPUnit_Model_Fixture_Interface extends EcomDev_PHPUnit_Model_
* @return EcomDev_PHPUnit_Model_Fixture_Interface
*/
public function loadForClass($className);
/**
* Sets fixture value
*
* @param string $key
* @param array[] $value
*
* @return EcomDev_PHPUnit_Model_Fixture_Interface
*/
public function setFixtureValue($key, $value);
/**
* Retrieves fixture value
*
* @param string $key
*
* @return array[]
*/
public function getFixtureValue($key);
/**
* Returns VFS wrapper instance
*
* @return EcomDev_PHPUnit_Model_Fixture_Vfs
*/
public function getVfs();
}
<?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) 2013 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) 2013 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) 2013 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)
{
$eavLoaders = array();
$this->getResource()->beginTransaction();
foreach ($data as $entityType => $values) {
$eavLoaders[] = $this->_getEavLoader($entityType)
->setFixture($fixture)
->setOptions($fixture->getOptions())
->loadEntity($entityType, $values);
}
$this->getResource()->commit();
foreach ($eavLoaders as $eavLoader){
$eavLoader->runRequiredIndexers();
}
$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) 2013 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) 2013 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>
*/
/**
* Registry fixture, works great for resetting singletons and other single instances in Magento
*
* Can be used by specifying annotations:
* @singleton catalog/product_type
* @resource catalog/product
* @helper catalog
*
* or by specifying it in Yaml file:
*
* registry:
* singleton:
* - catalog/product_type
* resource:
* - catalog/product
* helper
* - catalog
* - core/url
*
*/
class EcomDev_PHPUnit_Model_Fixture_Processor_Registry implements EcomDev_PHPUnit_Model_Fixture_Processor_Interface
{
const STORAGE_KEY = 'registry';
/**
* Clears singletons before tests
*
* @param array[] $data
* @param string $key
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
*
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Registry
* @throws RuntimeException
*/
public function apply(array $data, $key, EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$typeToKey = array(
'singleton' => '_singleton/',
'resource' => '_resource_singleton/',
'helper' => '_helper/'
);
if ($fixture->getStorageData(self::STORAGE_KEY) !== null) {
throw new RuntimeException('Registry data was not cleared after previous test');
}
$oldRegistry = array();
foreach ($data as $type => $keys) {
if (!isset($typeToKey[$type])) {
continue;
}
foreach ($keys as $key) {
// Preserve old registry value
$oldRegistry[$typeToKey[$type] . $key] = Mage::registry($typeToKey[$type] . $key);
// Set new value to registry
EcomDev_PHPUnit_Test_Case_Util::app()->replaceRegistry($typeToKey[$type] . $key, null);
}
}
$fixture->setStorageData(self::STORAGE_KEY, $oldRegistry);
return $this;
}
/**
* Sets back old singletons after tests
*
* @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)
{
if ($fixture->getStorageData(self::STORAGE_KEY) === null) {
return $this;
}
$oldRegistry = $fixture->getStorageData(self::STORAGE_KEY);
foreach ($oldRegistry as $key => $value) {
// Set old value to registry
EcomDev_PHPUnit_Test_Case_Util::app()->replaceRegistry($key, $value);
}
$fixture->setStorageData(self::STORAGE_KEY, null);
return $this;
}
/**
* Initializes fixture processor before applying data
*
* @param EcomDev_PHPUnit_Model_Fixture_Interface $fixture
* @return EcomDev_PHPUnit_Model_Fixture_Processor_Registry
*/
public function initialize(EcomDev_PHPUnit_Model_Fixture_Interface $fixture)
{
$options = $fixture->getOptions();
$registry = array();
foreach (array('singleton', 'resource', 'helper') as $type) {
if (!isset($options[$type])) {
continue;
}
foreach ($options[$type] as $name) {
$registry[$type][] = $name;
}
}
if ($registry) {
$fixture->setFixtureValue('registry', $registry);
}
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) 2013 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) 2013 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) 2013 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
{
const STORAGE_KEY = 'vfs';
/**
* 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)
{
if ($fixture->isScopeLocal()
&& ($parentData = $fixture->getStorageData(self::STORAGE_KEY,
EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED))) {
$data = array_merge_recursive($parentData, $data);
}
$fixture->getVfs()->apply($data);
$fixture->setStorageData(self::STORAGE_KEY, $data);
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();
$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) 2013 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>
*/
use org\bovigo\vfs\vfsStream as Stream;
use org\bovigo\vfs\vfsStreamDirectory as StreamDirectory;
use org\bovigo\vfs\vfsStreamWrapper as StreamWrapper;
use org\bovigo\vfs\visitor\vfsStreamStructureVisitor as StreamVisitor;
/**
* VFS library wrapper, to have simple api for manipulation with virtual fs
*
*
*/
class EcomDev_PHPUnit_Model_Fixture_Vfs
{
/**
* Current root directory stack of the VFS before apply process were started
*
* @var StreamDirectory[]
*/
protected $_currentRoot = array();
/**
* Initializes VFS stream wrapper/
*/
public function __construct()
{
Stream::setup();
}
/**
* Applies VFS directory structure
*
* @param $data
* @param bool $cloneCurrent
*
* @return EcomDev_PHPUnit_Model_Fixture_Vfs
*/
public function apply($data)
{
$this->_currentRoot[] = StreamWrapper::getRoot();
Stream::create($data);
return $this;
}
/**
* Discards VFS file system changes
*
* @return EcomDev_PHPUnit_Model_Fixture_Vfs
*/
public function discard()
{
if ($this->_currentRoot) {
StreamWrapper::setRoot(array_pop($this->_currentRoot));
}
return $this;
}
/**
* Dump current files structure
*
* @return array
*/
public function dump()
{
$currentRoot = StreamWrapper::getRoot();
if (!$currentRoot) {
return array();
}
$visitor = new StreamVisitor();
$visitor->visit($currentRoot);
return $visitor->getStructure();
}
/**
* Returns stream wrapper url for operation
* via built-in fs functions
*
* @param string $path
* @return string
*/
public function url($path)
{
return Stream::url($path);
}
}
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
* @author Steve Rice <srice@endertech.com>
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
* @author Steve Rice <srice@endertech.com>
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
* @author Steve Rice <srice@endertech.com>
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -31,15 +31,45 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract
protected $_requiredIndexers = array();
/**
* Retrieve required indexers for re-building
* Original list of indexers required to build
*
* @var array
*/
protected $_originalIndexers = array();
/**
* Retrieve required indexers for re-building
*
* @return array
*/
public function getRequiredIndexers()
{
return $this->_requiredIndexers;
}
/**
* Run required indexers and reset to original required indexers
*
* @return EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract
*/
public function runRequiredIndexers()
{
if (empty($this->_options['doNotIndexAll'])) {
$indexer = Mage::getSingleton('index/indexer');
foreach ($this->getRequiredIndexers() as $indexerCode) {
if (empty($this->_options['doNotIndex'])
|| !in_array($indexerCode, $this->_options['doNotIndex'])) {
$indexer->getProcessByCode($indexerCode)
->reindexAll();
}
}
}
// Restoring original required indexers for making tests isolated
$this->_requiredIndexers = $this->_originalIndexers;
return $this;
}
/**
* Add indexer by specific code to required indexers list
*
......@@ -78,7 +108,7 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract
*/
public function loadEntity($entityType, $values)
{
$originalRequiredIndexers = $this->_requiredIndexers;
$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)
......@@ -182,19 +212,6 @@ abstract class EcomDev_PHPUnit_Model_Mysql4_Fixture_Eav_Abstract
$this->_customEntityAction($entity, $entityTypeModel);
}
if (empty($this->_options['doNotIndexAll'])) {
$indexer = Mage::getSingleton('index/indexer');
foreach ($this->getRequiredIndexers() as $indexerCode) {
if (empty($this->_options['doNotIndex'])
|| !in_array($indexerCode, $this->_options['doNotIndex'])) {
$indexer->getProcessByCode($indexerCode)
->reindexAll();
}
}
}
// Restoring original required indexers for making tests isolated
$this->_requiredIndexers = $originalRequiredIndexers;
return $this;
}
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -25,10 +25,10 @@ interface EcomDev_PHPUnit_Model_Test_Loadable_Interface
/**
* Loads external data by test case instance
*
* @param EcomDev_PHPUnit_Test_Case $testCase
* @param PHPUnit_Framework_TestCase $testCase
* @return EcomDev_PHPUnit_Model_Test_Loadable_Interface
*/
public function loadByTestCase(EcomDev_PHPUnit_Test_Case $testCase);
public function loadByTestCase(PHPUnit_Framework_TestCase $testCase);
/**
* Applies external data
......
<?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) 2013 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) 2013 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
{
const DATA_DIR = '_data';
protected $_typeMap = array(
'fixtures' => 'fx',
'providers' => 'dp',
'expectations' => 'ex'
);
/**
* 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);
/**
* Looks in path for possible existent fixture
*
* @param string|array $path
* @param string $fileName
* @param string $type
* @return bool|string
*/
protected function _checkFilePath($path, $fileName, $type)
{
if (is_array($path)) {
foreach ($path as $value) {
if ($filePath = $this->_checkFilePath($value, $fileName, $type)) {
return $filePath;
}
}
return false;
}
if (isset($this->_typeMap[$type])
&& file_exists($filePath = $path . DS . self::DATA_DIR . DS . $this->_typeMap[$type] . '-' . $fileName)) {
return $filePath;
}
if (file_exists($filePath = $path . DS . $type . DS . $fileName)) {
return $filePath;
}
return false;
}
}
<?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) 2013 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 $this->_checkFilePath(array(
$fileObject->getPath(),
$fileObject->getPath() . DS . $fileObject->getBasename('.php')
), $fileName, $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) 2013 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) 2013 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 = false;
if (preg_match('#^~(?<module>[^/]*)/(?<fileName>.*)$#', $fileName, $matches)) {
$fileName = $matches['fileName'];
if(!empty($matches['module'])) {
$moduleName = $matches['module'];
}
}
if (!$moduleName) {
try {
$moduleName = EcomDev_PHPUnit_Test_Case_Util::getModuleNameByClassName($relatedClassName);
} catch (RuntimeException $e) {
return false;
}
}
$basePath = array();
if ($prefixPosition = strpos($relatedClassName, $moduleName . '_Test_')) {
$testType = substr($relatedClassName, $prefixPosition, strpos($relatedClassName, '_', $prefixPosition));
$basePath[] = Mage::getModuleDir('', $moduleName) . DS . 'Test' . DS . $testType;
}
$basePath[] = Mage::getModuleDir('', $moduleName) . DS . 'Test';
return $this->_checkFilePath($basePath, $fileName, $type);
}
}
......@@ -11,15 +11,11 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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,
// becuase Symfony component is not working propertly with nested associations
require_once 'Spyc/spyc.php';
/**
* Basic test case class
*
......@@ -28,14 +24,21 @@ require_once 'Spyc/spyc.php';
abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
{
const XML_PATH_DEFAULT_FIXTURE_MODEL = 'phpunit/suite/fixture/model';
const XML_PATH_DEFAULT_EXPECTATION_MODEL = 'phpunit/suite/expectation/model';
/**
* @deprecated since 0.3.0
**/
const XML_PATH_DEFAULT_FIXTURE_MODEL = EcomDev_PHPUnit_Test_Case_Util::XML_PATH_DEFAULT_FIXTURE_MODEL;
/**
* @deprecated since 0.3.0
**/
const XML_PATH_DEFAULT_EXPECTATION_MODEL = EcomDev_PHPUnit_Test_Case_Util::XML_PATH_DEFAULT_EXPECTATION_MODEL;
/**
* List of system registry values replaced by test case
*
* @var array
* @deprecated since 0.3.0
*/
protected $_replacedRegistry = array();
......@@ -52,6 +55,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* if was set in test method
*
* @var Mage_Core_Model_Store
* @deprecated since 0.3.0
*/
protected $_originalStore = null;
......@@ -63,7 +67,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
public static function app()
{
return Mage::app();
return EcomDev_PHPUnit_Test_Case_Util::app();
}
/**
......@@ -84,8 +88,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
/**
* Asserts that event was dispatched at least once
*
* @param string|array $event
* @param string $message
* @param array|string $eventName
*/
public static function assertEventDispatched($eventName)
{
......@@ -104,8 +107,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
/**
* Asserts that event was not dispatched
*
* @param string|array $event
* @param string $message
* @param string|array $eventName
*/
public static function assertEventNotDispatched($eventName)
{
......@@ -172,7 +174,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* is matched expected JSON structure
*
* @param array $expectedValue
* @param strign $matchType
* @param string $matchType
* @return EcomDev_PHPUnit_Constraint_Json
*/
public static function matchesJson(array $expectedValue, $matchType = EcomDev_PHPUnit_Constraint_Json::MATCH_AND)
......@@ -213,7 +215,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $string
* @param array $expectedValue
* @param string $message
* @param strign $matchType
* @param string $matchType
*/
public static function assertJsonMatch($string, array $expectedValue, $message = '',
$matchType = EcomDev_PHPUnit_Constraint_Json::MATCH_AND)
......@@ -252,10 +254,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*
* @return string
* @throws RuntimeException if module name was not found for the passed class name
* @deprecated since 0.3.0
*/
public function getModuleName()
{
return $this->app()->getModuleNameByClassName($this);
return EcomDev_PHPUnit_Test_Case_Util::getModuleName($this);
}
/**
......@@ -266,14 +269,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
protected static function getModuleNameFromCallStack()
{
$backTrace = debug_backtrace(true);
foreach ($backTrace as $call) {
if (isset($call['object']) && $call['object'] instanceof EcomDev_PHPUnit_Test_Case) {
return $call['object']->getModuleName();
}
}
throw new RuntimeException('Unable to retrieve module name from call stack, because assertion is not called from EcomDev_PHPUnit_Test_Case based class method');
return EcomDev_PHPUnit_Test_Case_Util::getModuleNameFromCallStack();
}
......@@ -284,10 +280,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $name
* @param array|string $sources
* @return array
* @deprecated since 0.3.0
*/
public function getAnnotationByName($name, $sources = 'method')
{
return self::getAnnotationByNameFromClass(get_class($this), $name, $sources, $this->getName(false));
return EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass(get_class($this), $name, $sources, $this->getName(false));
}
/**
......@@ -297,30 +294,12 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $name annotation name
* @param array|string $sources
* @param string $testName test method name
* @return array
* @deprecated since 0.3.0
*/
public static function getAnnotationByNameFromClass($className, $name, $sources = 'class', $testName = '')
{
if (is_string($sources)) {
$sources = array($sources);
}
$allAnnotations = PHPUnit_Util_Test::parseTestMethodAnnotations(
$className, $testName
);
$annotation = array();
// Walkthrough sources for annotation retrieval
foreach ($sources as $source) {
if (isset($allAnnotations[$source][$name])) {
$annotation = array_merge(
$allAnnotations[$source][$name],
$annotation
);
}
}
return $annotation;
return EcomDev_PHPUnit_Test_Case_Util::getAnnotationByNameFromClass($className, $name, $sources, $testName);
}
/**
......@@ -344,35 +323,10 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $type
* @param string $classAlias
* @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock
* @return EcomDev_PHPUnit_Test_Case
*/
protected function replaceByMock($type, $classAlias, $mock)
{
if ($mock instanceof PHPUnit_Framework_MockObject_MockBuilder) {
$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);
}
EcomDev_PHPUnit_Test_Case_Util::replaceByMock($type, $classAlias, $mock);
return $this;
}
......@@ -381,14 +335,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*
* @param string $key
* @param mixed $value
* @return EcomDev_PHPUnit_Test_Case
*/
protected function replaceRegistry($key, $value)
{
$oldValue = Mage::registry($key);
$this->app()->replaceRegistry($key, $value);
$this->_replacedRegistry[$key] = $oldValue;
EcomDev_PHPUnit_Test_Case_Util::replaceRegistry($key, $value);
return $this;
}
......@@ -396,31 +347,22 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* Shortcut for expectation data object retrieval
* Can be called with arguments array or in usual method
*
* @param string|array $pathFormat
* @param mixed $arg1
* @param mixed $arg2 ...
* @param string|array $firstArgument
* @optional @param mixed $arg1
* @optional @param mixed $arg2 ...
* @return Varien_Object
*/
protected function expected($firstArgument = null)
{
if (!$this->getExpectation()->isLoaded()) {
$this->getExpectation()->loadByTestCase($this);
$this->getExpectation()->apply();
}
if (!is_array($firstArgument)) {
if ($firstArgument === 'auto' && $this->readAttribute($this, 'dataName')) {
$arguments = $this->readAttribute($this, 'dataName');
} elseif (!is_array($firstArgument)) {
$arguments = func_get_args();
} else {
$arguments = $firstArgument;
}
$pathFormat = null;
if ($arguments) {
$pathFormat = array_shift($arguments);
}
return $this->getExpectation()
->getDataObject($pathFormat, $arguments);
return EcomDev_PHPUnit_Test_Case_Util::expected($this, $arguments);
}
/**
......@@ -660,43 +602,18 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
protected static function getFixture()
{
$fixture = Mage::getSingleton(
self::getLoadableClassAlias(
'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 (!$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;
return EcomDev_PHPUnit_Test_Case_Util::getFixture(get_called_class());
}
/**
* Returns expectation model singleton
*
* @return EcomDev_PHPUnit_Model_Expectation
* @deprecated since 0.3.0
*/
protected function getExpectation()
{
return Mage::getSingleton(
self::getLoadableClassAlias(
'expectation',
self::XML_PATH_DEFAULT_EXPECTATION_MODEL
)
);
return EcomDev_PHPUnit_Test_Case_Util::getExpectation(get_class($this));
}
......@@ -707,21 +624,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $type
* @param string $configPath
* @return string
* @deprecated since 0.3.0
*/
protected static function getLoadableClassAlias($type, $configPath)
{
$annotationValue = self::getAnnotationByNameFromClass(
get_called_class(),
$type .'Model'
);
if (current($annotationValue)) {
$classAlias = current($annotationValue);
} else {
$classAlias = (string) self::app()->getConfig()->getNode($configPath);
}
return $classAlias;
return EcomDev_PHPUnit_Test_Case_Util::getLoadableClassAlias(get_called_class(), $type, $configPath);
}
/**
......@@ -754,7 +661,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
$name = $this->getName(false);
}
return self::getYamlFilePathByClass(get_called_class(), $type, $name);
return EcomDev_PHPUnit_Test_Case_Util::getYamlFilePath(get_called_class(), $type, $name);
}
/**
......@@ -766,79 +673,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* @param string $type type of YAML data (fixtures,expectations,dataproviders)
* @param string $name the file name for loading
* @return string|boolean
* @depracated since 0.3.0
*/
public static function getYamlFilePathByClass($className, $type, $name)
{
if (strrpos($name, '.yaml') !== strlen($name) - 5) {
$name .= '.yaml';
}
$classFileObject = new SplFileInfo(
EcomDev_Utils_Reflection::getRelflection($className)->getFileName()
);
// When prefixed with ~/ or ~My_Module/, load from the module's Test/<type> directory
if (preg_match('#^~(?<module>[^/]*)/(?<path>.*)$#', $name, $matches)) {
$name = $matches['path'];
if( ! empty($matches['module'])) {
$moduleName = $matches['module'];
} else {
$moduleName = substr($className, 0, strpos($className, '_Test_'));;
}
$filePath = Mage::getModuleDir('', $moduleName) . DS . 'Test' . DS;
}
// 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;
}
return false;
}
/**
* Initializes a particular test environment
*
* (non-PHPdoc)
* @see PHPUnit_Framework_TestCase::setUp()
*/
protected function setUp()
{
self::getFixture()
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL)
->loadByTestCase($this);
$annotations = $this->getAnnotations();
self::getFixture()
->setOptions($annotations['method'])
->apply();
$this->app()->resetDispatchedEvents();
parent::setUp();
}
/**
* Initializes test environment for subset of tests
*
*/
public static function setUpBeforeClass()
{
self::getFixture()
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)
->loadForClass(get_called_class());
$annotations = PHPUnit_Util_Test::parseTestMethodAnnotations(
get_called_class()
);
self::getFixture()
->setOptions($annotations['class'])
->apply();
parent::setUpBeforeClass();
return EcomDev_PHPUnit_Test_Case_Util::getYamlFilePath($className, $type, $name);
}
/**
......@@ -850,15 +689,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
public function dataProvider($testName)
{
$this->setName($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);
return EcomDev_PHPUnit_Test_Case_Util::dataProvider(get_called_class(), $testName);
}
/**
......@@ -869,57 +700,7 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
public function setCurrentStore($store)
{
if (!$this->_originalStore) {
$this->_originalStore = $this->app()->getStore();
}
$this->app()->setCurrentStore(
$this->app()->getStore($store)
);
EcomDev_PHPUnit_Test_Case_Util::setCurrentStore($store);
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;
}
if ($this->getExpectation()->isLoaded()) {
$this->getExpectation()->discard();
}
$this->app()->getConfig()->flushReplaceInstanceCreation();
$this->app()->getLayout()->flushReplaceBlockCreation();
foreach ($this->_replacedRegistry as $registryPath => $originalValue) {
$this->app()->replaceRegistry($registryPath, $originalValue);
}
self::getFixture()
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL)
->discard(); // Clear applied fixture
parent::tearDown();
}
/**
* Clean up all the shared fixture data
*
* @return void
*/
public static function tearDownAfterClass()
{
self::getFixture()
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)
->discard();
parent::tearDownAfterClass();
}
}
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -180,11 +180,30 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas
);
}
/**
* Constraint for testing observer
* event definitions in configuration
*
* @param string $area
* @param string $routeName
* @param string $expectedValue
* @param string $type
* @return EcomDev_PHPUnit_Constraint_Config
*/
public static function configRouter($area, $routeName, $expectedValue,
$type = EcomDev_PHPUnit_Constraint_Config_Route::TYPE_MODULE)
{
return self::config(
new EcomDev_PHPUnit_Constraint_Config_Route($area, $routeName, $type, $expectedValue)
);
}
/**
* Executes configuration constraint
*
* @param EcomDev_PHPUnit_Constraint_Config $constraint
* @param string $message
* @param PHPUnit_Framework_Constraint $constraint
* @param string $message
* @return void
*/
public static function assertThatConfig(PHPUnit_Framework_Constraint $constraint, $message)
{
......@@ -1250,4 +1269,275 @@ abstract class EcomDev_PHPUnit_Test_Case_Config extends EcomDev_PHPUnit_Test_Cas
$message
);
}
/**
* Asserts that route frontName is the same as expected one
*
* If $frontName is empty, it uses $routeName as its expected value
*
* @param string $routeName
* @param string|null $frontName
* @param string $area
* @param string $message
*/
public static function assertRouteFrontName($routeName, $frontName = null,
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
if ($frontName === null) {
$frontName = $routeName;
}
self::assertThatConfig(
self::configRouter(
$area, $routeName, $frontName, EcomDev_PHPUnit_Constraint_Config_Route::TYPE_FRONT_NAME
),
$message
);
}
/**
* Asserts that route frontName is NOT the same as expected one
*
* If $frontName is empty, it uses $routeName as its expected value
*
* @param string $routeName
* @param string|null $frontName
* @param string $area
* @param string $message
*/
public static function assertRouteFrontNameNot($routeName, $frontName = null,
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
if ($frontName === null) {
$frontName = $routeName;
}
self::assertThatConfig(
self::logicalNot(
self::configRouter(
$area, $routeName, $frontName, EcomDev_PHPUnit_Constraint_Config_Route::TYPE_FRONT_NAME
)
),
$message
);
}
/**
* Asserts that route belongs to expected router
*
* @param string $routeName
* @param string $routerName
* @param string $area
* @param string $message
*/
public static function assertRouteIn($routeName, $routerName = 'standard',
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
self::assertThatConfig(
self::configRouter(
$area, $routeName, $routerName, EcomDev_PHPUnit_Constraint_Config_Route::TYPE_ROUTER
),
$message
);
}
/**
* Asserts that route DOES NOT belong to expected router
*
* @param string $routeName
* @param string $routerName
* @param string $area
* @param string $message
*/
public static function assertRouteNotIn($routeName, $routerName = 'standard',
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
self::assertThatConfig(
self::logicalNot(
self::configRouter(
$area, $routeName, $routerName, EcomDev_PHPUnit_Constraint_Config_Route::TYPE_ROUTER
)
),
$message
);
}
/**
* Asserts that route contains module as controller resolve path
*
* @param string $routeName
* @param string|null $moduleName
* @param string $area
* @param string $message
*/
public static function assertRouteModule($routeName, $moduleName = null,
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
if ($moduleName === null) {
$moduleName = self::getModuleNameFromCallStack();
}
self::assertThatConfig(
self::configRouter(
$area, $routeName, $moduleName
),
$message
);
}
/**
* Asserts that route DOES NOT contain module as controller resolve path
*
* @param string $routeName
* @param string|null $moduleName
* @param string $area
* @param string $message
*/
public static function assertRouteModuleNot($routeName, $moduleName = null,
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
if ($moduleName === null) {
$moduleName = self::getModuleNameFromCallStack();
}
self::assertThatConfig(
self::logicalNot(
self::configRouter(
$area, $routeName, $moduleName
)
),
$message
);
}
/**
* Asserts that route contains all expected modules in the same order in its controller resolve path
*
* @param string $routeName
* @param array $expectedModuleNames
* @param string $area
* @param string $message
*/
public static function assertRouteModuleOrder($routeName, array $expectedModuleNames,
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
self::assertThatConfig(
self::configRouter(
$area, $routeName, $expectedModuleNames, EcomDev_PHPUnit_Constraint_Config_Route::TYPE_MODULE_ORDER
),
$message
);
}
/**
* Asserts that route DOES NOT contain all expected modules in the same order in its controller resolve path
*
* @param string $routeName
* @param array $expectedModuleNames
* @param string $area
* @param string $message
*/
public static function assertRouteModuleOrderNot($routeName, array $expectedModuleNames,
$area = EcomDev_PHPUnit_Model_App::AREA_FRONTEND, $message = '')
{
self::assertThatConfig(
self::logicalNot(
self::configRouter(
$area, $routeName, $expectedModuleNames, EcomDev_PHPUnit_Constraint_Config_Route::TYPE_MODULE_ORDER
)
),
$message
);
}
/**
* Asserts that default config value matches expected type of constraint with expected value
*
* @param string $nodePath
* @param mixed $expectedValue
* @param string $message
* @param string $type
*/
public static function assertDefaultConfigValue($nodePath, $expectedValue, $message = '',
$type = EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_STRING)
{
$nodePath = 'default/' . $nodePath;
self::assertConfigNodeValue($nodePath, $expectedValue, $message, $type);
}
/**
* Asserts that default config value DOES NOT match expected type of constraint with expected value
*
* @param string $nodePath
* @param mixed $expectedValue
* @param string $message
* @param string $type
*/
public static function assertDefaultConfigValueNot($nodePath, $expectedValue, $message = '',
$type = EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_STRING)
{
$nodePath = 'default/' . $nodePath;
self::assertConfigNodeNotValue($nodePath, $expectedValue, $message, $type);
}
/**
* Asserts that store config value matches expected type of constraint with expected value
*
* @param string|int $store
* @param string $nodePath
* @param mixed $expectedValue
* @param string $message
* @param string $type
*/
public static function assertStoreConfigValue($store, $nodePath, $expectedValue, $message = '',
$type = EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_STRING)
{
$nodePath = 'stores/' . self::app()->getStore($store)->getCode() . '/' . $nodePath;
self::assertConfigNodeValue($nodePath, $expectedValue, $message, $type);
}
/**
* Asserts that store config value DOES NOT match expected type of constraint with expected value
*
* @param string|int $store
* @param string $nodePath
* @param mixed $expectedValue
* @param string $message
* @param string $type
*/
public static function assertStoreConfigValueNot($store, $nodePath, $expectedValue, $message = '',
$type = EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_STRING)
{
$nodePath = 'stores/' . self::app()->getStore($store)->getCode() . '/' . $nodePath;
self::assertConfigNodeNotValue($nodePath, $expectedValue, $message, $type);
}
/**
* Asserts that website config value matches expected type of constraint with expected value
*
* @param string|int $website
* @param string $nodePath
* @param mixed $expectedValue
* @param string $message
* @param string $type
*/
public static function assertWebsiteConfigValue($website, $nodePath, $expectedValue, $message = '',
$type = EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_STRING)
{
$nodePath = 'websites/' . self::app()->getWebsite($website)->getCode() . '/' . $nodePath;
self::assertConfigNodeValue($nodePath, $expectedValue, $message, $type);
}
/**
* Asserts that website config value DOES NOT match expected type of constraint with expected value
*
* @param string|int $website
* @param string $nodePath
* @param mixed $expectedValue
* @param string $message
* @param string $type
*/
public static function assertWebsiteConfigValueNot($website, $nodePath, $expectedValue, $message = '',
$type = EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_STRING)
{
$nodePath = 'websites/' . self::app()->getWebsite($website)->getCode() . '/' . $nodePath;
self::assertConfigNodeNotValue($nodePath, $expectedValue, $message, $type);
}
}
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -149,7 +149,7 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
*
* @param string $type
* @param string|null $expectedValue
* @return string
* @return EcomDev_PHPUnit_Constraint_Controller_Request
*/
public static function request($type, $expectedValue = null)
{
......@@ -162,7 +162,7 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
* @param string $type
* @param string $headerName
* @param PHPUnit_Framework_Constraint|null $constraint
* @return string
* @return EcomDev_PHPUnit_Constraint_Controller_Response_Header
*/
public static function responseHeader($headerName, $type, PHPUnit_Framework_Constraint $constraint = null)
{
......@@ -173,7 +173,7 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
* Controller response body constraint creation
*
* @param PHPUnit_Framework_Constraint $constraint
* @return string
* @return EcomDev_PHPUnit_Constraint_Controller_Response_Body
*/
public static function responseBody(PHPUnit_Framework_Constraint $constraint)
{
......@@ -523,12 +523,12 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
* Assert that response header is equal to expected value
*
* @param string $headerName
* @param mixed $expectedValue
* @param mixed $expectedValue
* @param string $message
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
* @param int $delta
* @param int $maxDepth
* @param bool $canonicalize
* @param bool $ignoreCase
*/
public static function assertResponseHeaderEquals($headerName, $expectedValue, $message = '',
$delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
......@@ -544,12 +544,12 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
* Assert that response header is not equal to expected value
*
* @param string $headerName
* @param mixed $expectedValue
* @param mixed $expectedValue
* @param string $message
* @param float $delta
* @param integer $maxDepth
* @param boolean $canonicalize
* @param boolean $ignoreCase
* @param int $delta
* @param int $maxDepth
* @param bool $canonicalize
* @param bool $ignoreCase
*/
public static function assertResponseHeaderNotEquals($headerName, $expectedValue, $message = '',
$delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
......@@ -633,7 +633,6 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
* @param string $headerName
* @param string $pcrePattern
* @param string $message
* @param boolean $ignoreCase
*/
public static function assertResponseHeaderRegExp($headerName, $pcrePattern, $message = '')
{
......@@ -650,7 +649,6 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
* @param string $headerName
* @param string $pcrePattern
* @param string $message
* @param boolean $ignoreCase
*/
public static function assertResponseHeaderNotRegExp($headerName, $pcrePattern, $message = '')
{
......@@ -871,7 +869,7 @@ abstract class EcomDev_PHPUnit_Test_Case_Controller extends EcomDev_PHPUnit_Test
$params['_store'] = EcomDev_PHPUnit_Model_App::ADMIN_STORE_CODE;
}
if ($params['_store'] === EcomDev_PHPUnit_Model_App::ADMIN_STORE_CODE) {
if (isset($params['_store']) && $params['_store'] === EcomDev_PHPUnit_Model_App::ADMIN_STORE_CODE) {
$urlModel = Mage::getModel('adminhtml/url');
} else {
$urlModel = Mage::getModel('core/url');
......
<?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) 2013 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
{
const XML_PATH_DEFAULT_FIXTURE_MODEL = 'phpunit/suite/fixture/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
* in the test case code
*
* @return EcomDev_PHPUnit_Model_App
*/
public static function app()
{
return Mage::app();
}
/**
* 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::$yamlLoaderModelAlias === 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 string|array $firstArgument
* @optional @param mixed $arg1
* @optional @param mixed $arg2
* @return Varien_Object
*/
public static function expected(PHPUnit_Framework_TestCase $testCase, $firstArgument = null)
{
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);
}
/**
* 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
*/
public static function getLoadableClassAlias($className, $type, $configPath)
{
$annotationValue = self::getAnnotationByNameFromClass(
$className,
$type .'Model'
);
if (current($annotationValue)) {
$classAlias = current($annotationValue);
} else {
$classAlias = (string) self::app()->getConfig()->getNode($configPath);
}
return $classAlias;
}
/**
* 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);
}
/**
* Retrieves annotation by its name from different sources (class, method) based on meta information
*
* @param string $className
* @param string $name annotation name
* @param array|string $sources
* @param string $testName test method name
* @return array
*/
public static function getAnnotationByNameFromClass($className, $name, $sources = 'class', $testName = '')
{
if (is_string($sources)) {
$sources = array($sources);
}
$allAnnotations = PHPUnit_Util_Test::parseTestMethodAnnotations(
$className, $testName
);
$annotation = array();
// Walkthrough sources for annotation retrieval
foreach ($sources as $source) {
if (isset($allAnnotations[$source][$name])) {
$annotation = array_merge(
$allAnnotations[$source][$name],
$annotation
);
}
}
return $annotation;
}
/**
* Retrieves module name from call stack objects
*
* @return string
* @throws RuntimeException if assertion is called in not from EcomDev_PHPUnit_Test_Case
*/
public static function getModuleNameFromCallStack()
{
$backTrace = debug_backtrace(true);
foreach ($backTrace as $call) {
if (isset($call['object']) && $call['object'] instanceof PHPUnit_Framework_TestCase) {
return self::getModuleName($call['object']);
}
}
throw new RuntimeException('Unable to retrieve module name from call stack, because assertion is not called from PHPUnit_Framework_Test_Case based class method');
}
/**
* Set current store scope for test
*
* @param int|string|Mage_Core_Model_Store $store
* @return void
*/
public static function setCurrentStore($store)
{
if (!self::$originalStore) {
self::$originalStore = self::app()->getStore();
}
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 string $className
* @param string $moduleName
* @return array
*/
public static function setModuleNameForClassName($className, $moduleName)
{
self::$moduleNameByClassName[$className] = $moduleName;
}
/**
* Returns module name for a particular object
*
* @param string|object $className
* @throws RuntimeException if module name was not found for the passed class name
* @return string
*/
public static function getModuleNameByClassName($className)
{
if (is_object($className)) {
$className = get_class($className);
}
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 (!$moduleName) {
throw new RuntimeException('Cannot to find the module name for class name: ' . $className);
}
self::setModuleNameForClassName($className, $moduleName);
}
return self::$moduleNameByClassName[$className];
}
/**
* Replaces Magento resource by mock object
*
* @param string $type
* @param string $classAlias
* @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock
* @return void
*
* @throws InvalidArgumentException
*/
public static function replaceByMock($type, $classAlias, $mock)
{
if ($mock instanceof PHPUnit_Framework_MockObject_MockBuilder) {
$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'))) {
self::app()->getConfig()->replaceInstanceCreation($type, $classAlias, $mock);
$type = str_replace('model', 'singleton', $type);
} elseif ($type == 'block') {
self::app()->getLayout()->replaceBlockCreation($classAlias, $mock);
}
if (in_array($type, array('singleton', 'resource_singleton', 'helper'))) {
$registryPath = '_' . $type . '/' . $classAlias;
self::replaceRegistry($registryPath, $mock);
}
}
/**
* 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;
}
/**
* 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 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) 2013 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
{
const XML_PATH_UNIT_TEST_APP = 'phpunit/suite/app/class';
/**
* First level test suite that is used
* for running all the tests
*
* @var PHPUnit_Framework_TestSuite
*/
protected $firstLevelTestSuite = null;
/**
* Returns app reflection instance
*
* @return ReflectionClass|ReflectionObject
*/
protected function getAppReflection()
{
$appClass = (string) Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_APP);
$reflectionClass = EcomDev_Utils_Reflection::getReflection($appClass);
return $reflectionClass;
}
/**
* A test suite started.
*
* @param PHPUnit_Framework_TestSuite $suite
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
{
if ($this->firstLevelTestSuite === null) {
// Apply app substitution for tests
if ($this->getAppReflection()->hasMethod('applyTestScope')) {
$this->getAppReflection()->getMethod('applyTestScope')->invoke(null);
}
$this->firstLevelTestSuite = $suite;
}
if (EcomDev_Utils_Reflection::getRestrictedPropertyValue($suite, 'testCase')) {
EcomDev_PHPUnit_Test_Case_Util::getFixture($suite->getName())
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_SHARED)
->loadForClass($suite->getName());
$annotations = PHPUnit_Util_Test::parseTestMethodAnnotations(
$suite->getName()
);
EcomDev_PHPUnit_Test_Case_Util::getFixture($suite->getName())
->setOptions($annotations['class'])
->apply();
}
}
/**
* A test suite ended.
*
* @param 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) {
$this->firstLevelTestSuite = null;
// Discard test scope app
if ($this->getAppReflection()->hasMethod('discardTestScope')) {
$this->getAppReflection()->getMethod('discardTestScope')->invoke(null);
}
}
}
/**
* A test started.
*
* @param PHPUnit_Framework_Test $test
*/
public function startTest(PHPUnit_Framework_Test $test)
{
if ($test instanceof PHPUnit_Framework_TestCase) {
EcomDev_PHPUnit_Test_Case_Util::getFixture(get_class($test))
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL)
->loadByTestCase($test);
$annotations = $test->getAnnotations();
EcomDev_PHPUnit_Test_Case_Util::getFixture()
->setOptions($annotations['method'])
->apply();
EcomDev_PHPUnit_Test_Case_Util::setUp();
}
}
/**
* A test ended.
*
* @param PHPUnit_Framework_Test $test
* @param float $time
*/
public function endTest(PHPUnit_Framework_Test $test, $time)
{
if ($test instanceof PHPUnit_Framework_TestCase) {
EcomDev_PHPUnit_Test_Case_Util::getFixture(get_class($test))
->setScope(EcomDev_PHPUnit_Model_Fixture_Interface::SCOPE_LOCAL)
->discard(); // Clear applied fixture
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::tearDown();
}
}
/**
* An error occurred.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
{
// No action is required
}
/**
* A failure occurred.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_AssertionFailedError $e
* @param float $time
*/
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
{
// No action is required
}
/**
* Incomplete test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
// No action is required
}
/**
* Skipped test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
{
// No action is required
}
}
\ No newline at end of file
......@@ -11,12 +11,11 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
/**
* Test suite for Magento
*
......@@ -34,36 +33,6 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
const CACHE_TAG = 'ECOMDEV_PHPUNIT';
const CACHE_TYPE = 'ecomdev_phpunit';
/**
* Setting up test scope for Magento
* (non-PHPdoc)
* @see PHPUnit_Framework_TestSuite::setUp()
*/
protected function setUp()
{
$appClass = (string) Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_APP);
$reflectionClass = EcomDev_Utils_Reflection::getRelflection($appClass);
if ($reflectionClass->hasMethod('applyTestScope')) {
$reflectionClass->getMethod('applyTestScope')->invoke(null);
}
}
/**
* Returning Magento to the state before suite was run
* (non-PHPdoc)
* @see PHPUnit_Framework_TestSuite::tearDown()
*/
protected function tearDown()
{
$appClass = (string) Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_APP);
$reflectionClass = EcomDev_Utils_Reflection::getRelflection($appClass);
if ($reflectionClass->hasMethod('discardTestScope')) {
$reflectionClass->getMethod('discardTestScope')->invoke(null);
}
}
/**
* This method loads all available test suites for PHPUnit
*
......@@ -73,7 +42,7 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
{
$groups = Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_GROUPS);
$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')) {
new RuntimeException('Test Suite class should be extended from EcomDev_PHPUnit_Test_Suite_Group');
......@@ -153,10 +122,10 @@ class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
$className = uc_words(ltrim($classPath, DS), '_', DS);
// 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 PHPUnit_Framework_TestCase
if (class_exists($className, true)) {
$reflectionClass = EcomDev_Utils_Reflection::getRelflection($className);
if (!$reflectionClass->isSubclassOf('EcomDev_PHPUnit_Test_Case')
$reflectionClass = EcomDev_Utils_Reflection::getReflection($className);
if (!$reflectionClass->isSubclassOf('PHPUnit_Framework_TestCase')
|| $reflectionClass->isAbstract()) {
continue;
}
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -42,7 +42,7 @@ class EcomDev_PHPUnit_Test_Suite_Group extends PHPUnit_Framework_TestSuite
public function __construct($theClass = '', $groups = array())
{
if (!$theClass instanceof ReflectionClass) {
$theClass = EcomDev_Utils_Reflection::getRelflection($theClass);
$theClass = EcomDev_Utils_Reflection::getReflection($theClass);
}
// Check annotations for test case name
......
<?php
require 'app/Mage.php';
if (version_compare(PHP_VERSION, '5.3', '<')) {
exit('Magento Unit Tests can be runned only on PHP version over 5.3');
echo 'Magento Unit Tests can run only on PHP version higher then 5.3';
exit(1);
}
$_baseDir = getcwd();
// Include Mage file by detecting app root
require_once $_baseDir . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'Mage.php';
if (!Mage::isInstalled()) {
exit('Magento Unit Tests can be runned only on installed version');
echo 'Magento Unit Tests can run only on installed version';
exit(1);
}
/* Replace server variables for proper file naming */
$_SERVER['SCRIPT_NAME'] = dirname(__FILE__) . DS . 'index.php';
$_SERVER['SCRIPT_FILENAME'] = dirname(__FILE__) . DS . 'index.php';
$_SERVER['SCRIPT_NAME'] = $_baseDir . DS . 'index.php';
$_SERVER['SCRIPT_FILENAME'] = $_baseDir . DS . 'index.php';
Mage::app('admin');
Mage::getConfig()->init();
class UnitTests extends EcomDev_PHPUnit_Test_Suite
{
}
......@@ -12,7 +12,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -45,6 +45,14 @@
</global>
<phpunit>
<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 -->
<groups>
<models>Model</models>
......@@ -70,6 +78,16 @@
<fixture>
<!-- Default model for loading of fixtures -->
<model>ecomdev_phpunit/fixture</model>
<processors>
<registry>ecomdev_phpunit/fixture_processor_registry</registry>
<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>
<attribute>
<!-- Fixture loaders for EAV attributes
Default can be used but does not support extra attribute table configuration -->
......
<?php
class EcomDev_PHPUnitTest_Test_Lib_Constraint_Abstract extends PHPUnit_Framework_TestCase
{
/**
* Test compare values functionality for constraint
*
* @param mixed $expectedValue
* @param mixed $actualValue
* @param bool $expectedResult
*
* @dataProvider dataProviderForCompareValues
*/
public function testCompareValues($expectedValue, $actualValue, $expectedResult)
{
/**
* @var $constraint EcomDev_PHPUnit_Constraint_Abstract
*/
$constraint = $this->getMockForAbstractClass('EcomDev_PHPUnit_Constraint_Abstract', array(), '', false);
$this->assertSame(
$expectedResult,
$constraint->compareValues($expectedValue, $actualValue)
);
if (!$expectedResult) {
$this->assertAttributeInstanceOf('PHPUnit_Framework_ComparisonFailure', '_comparisonFailure', $constraint);
}
}
/**
* Data provider for checking compare values functionality
*
* @return array
*/
public function dataProviderForCompareValues()
{
return array(
array(
array('value1', 'value2', 'value3'),
array('value1', 'value2', 'value3'),
true
),
array(
array('value1', 'value2', 'value3'),
array('value1', 'value1', 'value3'),
false
),
array(
array('value1', 0, 'value3'),
array('value1', 'value1', 'value3'),
false
),
array(
'1',
1,
true
),
array(
'0',
0,
true
),
array(
'1',
0,
false
),
array(
'',
0,
false
)
);
}
}
\ No newline at end of file
<?php
class EcomDev_PHPUnitTest_Test_Lib_Constraint_Config_Node extends EcomDev_PHPUnit_Test_Case
{
/**
* Creates constraint instance
*
* @param $nodePath
* @param $type
* @param $value
*
* @return EcomDev_PHPUnit_Constraint_Config_Node
*/
protected function _getConstraint($nodePath, $type, $value)
{
return new EcomDev_PHPUnit_Constraint_Config_Node($nodePath, $type, $value);
}
/**
* Test constructor of the node,
*
* @param mixed $expectedValue
* @param string $type
*
* @dataProvider dataProvider
*/
public function testConstructorAccepts($expectedValue, $type)
{
$constraint = $this->_getConstraint('some/dummy/path', $type, $expectedValue);
$this->assertAttributeEquals($expectedValue, '_expectedValue', $constraint);
}
/**
* Tests that particular value equals xml
*
* @param string $actualValue
* @param string $expectedValue
* @dataProvider dataProvider
*/
public function testEqualsXml($actualValue, $expectedValue)
{
$actualValue = new SimpleXMLElement($actualValue);
$expectedValue = new SimpleXMLElement($expectedValue);
$constraint = $this->_getConstraint(
'some/dummy/path',
EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_XML,
$expectedValue
);
$this->assertTrue($constraint->evaluate($actualValue, '', true));
$this->assertAttributeEmpty('_comparisonFailure', $constraint);
}
/**
* Tests that particular value equals xml
*
* @param string $actualValue
* @param string $expectedValue
* @dataProvider dataProvider
*/
public function testEqualsXmlFailure($actualValue, $expectedValue)
{
$actualValue = new SimpleXMLElement($actualValue);
$expectedValue = new SimpleXMLElement($expectedValue);
$constraint = $this->_getConstraint(
'some/dummy/path',
EcomDev_PHPUnit_Constraint_Config_Node::TYPE_EQUALS_XML,
$expectedValue
);
$this->assertFalse($constraint->evaluate($actualValue, '', true));
$this->assertAttributeNotEmpty('_comparisonFailure', $constraint);
$this->assertAttributeInstanceOf('PHPUnit_Framework_ComparisonFailure', '_comparisonFailure', $constraint);
}
}
\ No newline at end of file
-
- 1
- equals_string
-
- '0'
- equals_string
-
- 0.01
- equals_string
-
- "0.01"
- equals_decimal
-
- "0"
- equals_decimal
-
- "100.0123"
- equals_decimal
-
actual: |
<config>
<value>1</value>
<value>2</value>
</config>
expected: |
<config>
<value>1</value>
<value>2</value>
</config>
-
actual: |
<config>
<value>1</value>
<value>2</value>
</config>
expected: |
<config>
<value>1</value>
<value>2</value>
</config>
-
actual: |
<config>
<value>1</value>
<value>2</value>
<more_nested><value>1</value><value>2</value></more_nested>
</config>
expected: |
<config>
<value>1</value>
<value>2</value>
<more_nested>
<value>1</value>
<value>2</value>
</more_nested>
</config>
\ No newline at end of file
-
actual: |
<config>
<value>1</value>
<value>2</value>
</config>
expected: |
<config>
<value>2</value>
<value>3</value>
</config>
-
actual: |
<config>
<value>1</value>
<value>2</value>
<more_nested>
<value>1</value>
<value>2</value>
</more_nested>
</config>
expected: |
<config>
<value>1</value>
<value>2</value>
<more_nested>
<value>1</value>
<value>1</value>
</more_nested>
</config>
\ No newline at end of file
<?php
/**
* A test case for testing script assertions
*
* @loadSharedFixture files
*/
class EcomDev_PHPUnitTest_Test_Lib_Constraint_Config_Resource_Script extends EcomDev_PHPUnit_Test_Case
{
/**
* @var EcomDev_PHPUnit_Constraint_Config_Resource_Script
*/
protected $constraint = null;
protected function setUp()
{
$this->constraint = $this->getMockBuilder('EcomDev_PHPUnit_Constraint_Config_Resource_Script')
->disableOriginalConstructor()
->setMethods(null)
->getMock();
}
/**
* Returns path within vfs stream
*
* @param string[]|string $directories
* @return string[]|string
*/
protected function getVirtualPath($directories)
{
if (!is_array($directories)) {
$directories = array($directories);
}
$virtualPath = array();
foreach ($directories as $directory) {
$virtualPath[] = $this->getFixture()->getVfs()->url($directory);
}
if (count($virtualPath) === 1) {
$virtualPath = current($virtualPath);
}
return $virtualPath;
}
/**
*
* @param $directory
* @dataProvider dataProvider
*/
public function testParseVersions($directories)
{
$virtualPath = $this->getVirtualPath($directories);
$result = EcomDev_Utils_Reflection::invokeRestrictedMethod($this->constraint, 'parseVersions', array($virtualPath));
$this->assertEquals($this->expected('auto')->getVersions(), $result);
}
/**
* Test version
*
* @param string[]|string $directories
* @param string $type
* @param string $from
* @param string $to
*
* @return void
* @dataProvider dataProvider
*/
public function testGetVersionScriptsDiff($directories, $type, $from, $to)
{
$virtualPath = $this->getVirtualPath($directories);
$versions = EcomDev_Utils_Reflection::invokeRestrictedMethod($this->constraint, 'parseVersions', array(
$virtualPath
));
$result = EcomDev_Utils_Reflection::invokeRestrictedMethod($this->constraint, 'getVersionScriptsDiff', array(
$versions[$type], $from, $to, $type === 'data' ? 'data-' : ''
));
$this->assertEquals($this->expected('auto')->getDiff(), $result);
}
}
\ No newline at end of file
from_1.0.0_to_1.0.1_one:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
actual:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
from_1.0.0_to_1.0.5_one:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
- upgrade-1.0.1-1.0.5.php
actual:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
to_1.0.5_one:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
- upgrade-1.0.1-1.0.5.php
actual:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
from_1.0.0_one:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
actual:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
from_1.0.0_to_1.0.1_one_invalid:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
actual:
- upgrade-1.0.0-1.0.1.php
from_1.0.0_to_1.0.5_one_invalid:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
- upgrade-1.0.1-1.0.5.php
actual:
- upgrade-1.0.0-1.0.1.php
from_1.0.0_one_invalid:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
actual:
- upgrade-1.0.0-1.0.1.php
to_1.0.5_one_invalid:
diff:
expected:
- install-1.0.0.php
- upgrade-1.0.0-1.0.1.php
- upgrade-1.0.1-1.0.5.php
actual:
- upgrade-1.0.0-1.0.1.php
\ No newline at end of file
directory_one_valid:
versions:
scheme:
install:
- filename: install-1.0.0.php
prefix: install
from: 1.0.0
to: null
- filename: mysql4-install-0.8.0.php
prefix: mysql4-install
from: 0.8.0
to: null
upgrade:
- filename: upgrade-1.0.0-1.0.1.php
prefix: upgrade
from: 1.0.0
to: 1.0.1
- filename: mysql4-upgrade-0.8.0-0.8.1.php
prefix: mysql4-upgrade
from: 0.8.0
to: 0.8.1
data:
install: []
upgrade: []
directory_two_valid:
versions:
scheme:
install:
- filename: install-1.0.0.php
prefix: install
from: 1.0.0
to: null
- filename: mysql4-install-0.8.0.php
prefix: mysql4-install
from: 0.8.0
to: null
upgrade:
- filename: upgrade-1.0.0-1.0.1.php
prefix: upgrade
from: 1.0.0
to: 1.0.1
- filename: upgrade-1.0.1-1.0.2.php
prefix: upgrade
from: 1.0.1
to: 1.0.2
- filename: upgrade-1.0.2-1.0.3.php
prefix: upgrade
from: 1.0.2
to: 1.0.3
- filename: upgrade-1.0.3-1.0.4.php
prefix: upgrade
from: 1.0.3
to: 1.0.4
- filename: mysql4-upgrade-0.8.0-0.8.1.php
prefix: mysql4-upgrade
from: 0.8.0
to: 0.8.1
- filename: mysql4-upgrade-0.8.1-0.8.2.php
prefix: mysql4-upgrade
from: 0.8.1
to: 0.8.2
- filename: mysql4-upgrade-0.8.2-0.8.3.php
prefix: mysql4-upgrade
from: 0.8.2
to: 0.8.3
- filename: mysql4-upgrade-0.8.3-0.8.4.php
prefix: mysql4-upgrade
from: 0.8.3
to: 0.8.4
data:
install: []
upgrade: []
directory_one_data_scheme_valid:
versions:
scheme:
install:
- filename: install-1.0.0.php
prefix: install
from: 1.0.0
to: null
upgrade:
- filename: upgrade-1.0.0-1.0.1.php
prefix: upgrade
from: 1.0.0
to: 1.0.1
- filename: upgrade-1.0.1-1.0.2.php
prefix: upgrade
from: 1.0.1
to: 1.0.2
- filename: upgrade-1.0.2-1.0.3.php
prefix: upgrade
from: 1.0.2
to: 1.0.3
- filename: upgrade-1.0.3-1.0.4.php
prefix: upgrade
from: 1.0.3
to: 1.0.4
data:
install:
- filename: data-install-1.0.0.php
prefix: data-install
from: 1.0.0
to: null
upgrade:
- filename: data-upgrade-1.0.0-1.0.1.php
prefix: data-upgrade
from: 1.0.0
to: 1.0.1
- filename: data-upgrade-1.0.1-1.0.2.php
prefix: data-upgrade
from: 1.0.1
to: 1.0.2
- filename: data-upgrade-1.0.2-1.0.3.php
prefix: data-upgrade
from: 1.0.2
to: 1.0.3
- filename: data-upgrade-1.0.3-1.0.4.php
prefix: data-upgrade
from: 1.0.3
to: 1.0.4
directory_one_invalid:
versions:
scheme:
install: []
upgrade:
- filename: upgrade-1.0.0-1.0.1.php
prefix: upgrade
from: 1.0.0
to: 1.0.1
data:
install: []
upgrade: []
directory_two_invalid:
versions:
scheme:
install:
- filename: install-1.0.0.php
prefix: install
from: 1.0.0
to: null
upgrade:
- filename: upgrade-1.0.1-1.0.2.php
prefix: upgrade
from: 1.0.1
to: 1.0.2
- filename: upgrade-1.0.2-1.0.3.php
prefix: upgrade
from: 1.0.2
to: 1.0.3
- filename: upgrade-1.0.3-1.0.4.php
prefix: upgrade
from: 1.0.3
to: 1.0.4
data:
install: []
upgrade: []
directory_one_data_scheme_invalid:
versions:
scheme:
install:
- filename: install-1.0.0.php
prefix: install
from: 1.0.0
to: null
upgrade:
- filename: upgrade-1.0.0-1.0.1.php
prefix: upgrade
from: 1.0.0
to: 1.0.1
- filename: upgrade-1.0.1-1.0.2.php
prefix: upgrade
from: 1.0.1
to: 1.0.2
- filename: upgrade-1.0.2-1.0.3.php
prefix: upgrade
from: 1.0.2
to: 1.0.3
- filename: upgrade-1.0.3-1.0.4.php
prefix: upgrade
from: 1.0.3
to: 1.0.4
data:
install:
- filename: data-install-1.0.0.php
prefix: data-install
from: 1.0.0
to: null
upgrade:
- filename: data-upgrade-1.0.1-1.0.2.php
prefix: data-upgrade
from: 1.0.1
to: 1.0.2
- filename: data-upgrade-1.0.2-1.0.3.php
prefix: data-upgrade
from: 1.0.2
to: 1.0.3
- filename: data-upgrade-1.0.3-1.0.4.php
prefix: data-upgrade
from: 1.0.3
to: 1.0.4
\ No newline at end of file
vfs:
directory_one_valid:
install-1.0.0.php: <?php // file
upgrade-1.0.0-1.0.1.php: <?php // file
mysql4-install-0.8.0.php: <?php // file
mysql4-upgrade-0.8.0-0.8.1.php: <?php // file
directory_two_valid:
install-1.0.0.php: <?php // file
upgrade-1.0.0-1.0.1.php: <?php // file
upgrade-1.0.1-1.0.2.php: <?php // file
upgrade-1.0.2-1.0.3.php: <?php // file
upgrade-1.0.3-1.0.4.php: <?php // file
mysql4-install-0.8.0.php: <?php // file
mysql4-upgrade-0.8.0-0.8.1.php: <?php // file
mysql4-upgrade-0.8.1-0.8.2.php: <?php // file
mysql4-upgrade-0.8.2-0.8.3.php: <?php // file
mysql4-upgrade-0.8.3-0.8.4.php: <?php // file
directory_one_data_valid:
data-install-1.0.0.php: <?php // file
data-upgrade-1.0.0-1.0.1.php: <?php // file
data-upgrade-1.0.1-1.0.2.php: <?php // file
data-upgrade-1.0.2-1.0.3.php: <?php // file
data-upgrade-1.0.3-1.0.4.php: <?php // file
directory_one_scheme_valid:
install-1.0.0.php: <?php // file
upgrade-1.0.0-1.0.1.php: <?php // file
upgrade-1.0.1-1.0.2.php: <?php // file
upgrade-1.0.2-1.0.3.php: <?php // file
upgrade-1.0.3-1.0.4.php: <?php // file
directory_one_invalid:
instal-1.0.0.php: <?php // file # error in install script file name
upgrade-1.0.0-1.0.1.php: <?php // file
directory_two_invalid:
install-1.0.0.php: <?php // file
update-1.0.0-1.0.1.php: <?php // file # error in upgrade script file name
upgrade-1.0.1-1.0.2.php: <?php // file
upgrade-1.0.2-1.0.3.php: <?php // file
upgrade-1.0.3-1.0.4.php: <?php // file
directory_one_data_invalid:
data-install-1.0.0.php: <?php // file
data-upgade-1.0.0-1.0.1.php: <?php // file # error in the filename
data-upgrade-1.0.1-1.0.2.php: <?php // file
data-upgrade-1.0.2-1.0.3.php: <?php // file
data-upgrade-1.0.3-1.0.4.php: <?php // file
\ No newline at end of file
from_1.0.0_to_1.0.1_one:
- directory_one_valid
- scheme
- 1.0.0
- 1.0.1
from_1.0.0_to_1.0.5_one:
- directory_one_valid
- scheme
- 1.0.0
- 1.0.5
to_1.0.5_one:
- directory_one_valid
- scheme
- null
- 1.0.5
from_1.0.0_one:
- directory_one_valid
- scheme
- 1.0.0
- null
from_1.0.0_to_1.0.1_one_invalid:
- directory_one_invalid
- scheme
- 1.0.0
- 1.0.1
from_1.0.0_to_1.0.5_one_invalid:
- directory_one_invalid
- scheme
- 1.0.0
- 1.0.5
from_1.0.0_one_invalid:
- directory_one_invalid
- scheme
- 1.0.0
- null
to_1.0.5_one_invalid:
- directory_one_invalid
- scheme
- null
- 1.0.5
directory_one_valid:
- directory_one_valid
directory_two_valid:
- directory_two_valid
directory_one_data_scheme_valid:
-
- directory_one_data_valid
- directory_one_scheme_valid
directory_one_invalid:
- directory_one_invalid
directory_two_invalid:
- directory_two_invalid
directory_one_data_scheme_invalid:
-
- directory_one_data_invalid
- directory_one_scheme_valid
\ No newline at end of file
<config>
<phpunit>
<suite>
<modules>
<EcomDev_PHPUnitTest />
</modules>
<groups>
<lib>Lib</lib>
</groups>
</suite>
</phpunit>
</config>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* 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) 2013 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>
*/
-->
<config>
<modules>
<EcomDev_PHPUnitTest>
<codePool>community</codePool>
<active>true</active>
</EcomDev_PHPUnitTest>
</modules>
</config>
\ No newline at end of file
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -20,7 +20,6 @@
* Abstract constraint for EcomDev_PHPUnit constraints
* Contains flexible constaint types implementation
*
* @todo refactor failures for being 100% compatible with PHPUnit 3.6
*/
abstract class EcomDev_PHPUnit_Constraint_Abstract
extends PHPUnit_Framework_Constraint
......@@ -74,16 +73,25 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
*/
protected $_useActualValue = false;
/**
* Comparison failure for nice failure messages
*
* @var PHPUnit_Framework_ComparisonFailure
*/
protected $_comparisonFailure = null;
/**
* Abstract cnstraint constructor,
* provides unified interface for working with multiple types of evalation
*
* @param string $type
* @param mixed $expectedValue
* @param mixed $expectedValue
*
* @throws PHPUnit_Framework_Exception
*/
public function __construct($type, $expectedValue = null)
{
$reflection = EcomDev_Utils_Reflection::getRelflection(get_class($this));
$reflection = EcomDev_Utils_Reflection::getReflection(get_class($this));
$types = array();
foreach ($reflection->getConstants() as $name => $constant) {
if (strpos($name, 'TYPE_') === 0) {
......@@ -98,7 +106,7 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
if (isset($this->_expectedValueValidation[$type])) {
$expectedValueType = (isset($this->_expectedValueValidation[$type][2]) ?
isset($this->_expectedValueValidation[$type][2]) :
$this->_expectedValueValidation[$type][2] :
'');
// Mandatory check
......@@ -188,12 +196,7 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
if (in_array($this->_type, $this->_typesWithDiff)) {
throw new EcomDev_PHPUnit_Constraint_Exception(
$failureDescription,
new PHPUnit_Framework_ComparisonFailure(
$this->getExpectedValue(),
$this->getActualValue($other),
$this->getExpectedValue(),
$this->getActualValue($other)
),
$this->getComparisonFailure($this->getExpectedValue(), $this->getActualValue($other)),
$description
);
} else {
......@@ -255,4 +258,80 @@ abstract class EcomDev_PHPUnit_Constraint_Abstract
{
return $this->callProtectedByType('text');
}
/**
* Exports value as string
*
* @param mixed $value
* @return string
*/
public function exportAsString($value)
{
if (is_array($value) && preg_match('/^\d+$/', implode('', array_keys($value)))) {
$stringValue = '';
foreach ($value as $val) {
$stringValue .= (is_string($val) ? $val : PHPUnit_Util_Type::export($val)) . "\n";
}
return $stringValue;
} else {
return PHPUnit_Util_Type::export($value);
}
}
/**
* Compares two values by using correct comparator for two types
*
* @param mixed $expectedValue
* @param mixed $actualValue
* @return bool
*/
public function compareValues($expectedValue, $actualValue)
{
$comparatorFactory = PHPUnit_Framework_ComparatorFactory::getDefaultInstance();
try {
$comparator = $comparatorFactory->getComparatorFor(
$expectedValue, $actualValue
);
$comparator->assertEquals(
$expectedValue,
$actualValue
);
}
catch (PHPUnit_Framework_ComparisonFailure $f) {
$this->_comparisonFailure = $f;
return false;
}
return true;
}
/**
* Retrieve comparison failure exception.
*
* Is used for generation of the failure messages
*
* @param mixed $actualValue
* @param mixed $expectedValue
*
* @return PHPUnit_Framework_ComparisonFailure
*/
public function getComparisonFailure($actualValue, $expectedValue)
{
if ($this->_comparisonFailure !== null) {
$failure = $this->_comparisonFailure;
$this->_comparisonFailure = null;
return $failure;
}
return new PHPUnit_Framework_ComparisonFailure(
$expectedValue,
$actualValue,
$this->exportAsString($expectedValue),
$this->exportAsString($actualValue)
);
}
}
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -79,7 +79,7 @@ class EcomDev_PHPUnit_Constraint_Config extends PHPUnit_Framework_Constraint
if ($nodeValue === false) {
throw new EcomDev_PHPUnit_Constraint_Exception(
sprintf('Invalid node path specified for evaluation %s', $this->constraint->getNodePath())
sprintf('Cannot find any node in specified path: %s', $this->constraint->getNodePath())
);
}
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -86,7 +86,7 @@ abstract class EcomDev_PHPUnit_Constraint_Config_Abstract
protected function getActualValue($other = null)
{
if (!$this->_useActualValue && $other->hasChildren()) {
return $other->asNiceXml();
return $this->getXmlAsDom($this->_expectedValue);
} elseif (!$this->_useActualValue) {
return (string) $other;
}
......@@ -102,9 +102,28 @@ abstract class EcomDev_PHPUnit_Constraint_Config_Abstract
protected function getExpectedValue()
{
if ($this->_expectedValue instanceof Varien_Simplexml_Element) {
return $this->_expectedValue->asNiceXml();
return $this->getXmlAsDom($this->_expectedValue);
}
return parent::getExpectedValue();
}
/**
* Converts xml to dom object
*
* @param $xmlValue
* @return DOMDocument
*/
protected function getXmlAsDom($xmlValue)
{
if ($xmlValue instanceof SimpleXMLElement) {
$xmlValue = $xmlValue->asXML();
}
$domValue = new DOMDocument;
$domValue->preserveWhiteSpace = FALSE;
$domValue->loadXML($xmlValue);
return $domValue;
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -90,6 +90,7 @@ class EcomDev_PHPUnit_Constraint_Config_Layout
);
$this->_typesWithDiff[] = self::TYPE_LAYOUT_FILE;
$this->_typesWithDiff[] = self::TYPE_LAYOUT_DEFINITION;
$nodePath = sprintf(self::XML_PATH_LAYOUT, $area);
......@@ -131,7 +132,18 @@ class EcomDev_PHPUnit_Constraint_Config_Layout
}
}
return false;
if ($this->_layoutUpdate === null) {
$this->_layoutUpdate = 'your_module';
}
$expected = clone $other;
$expected->addChild($this->_layoutUpdate)
->addChild('file', htmlspecialchars($this->_expectedValue));
return $this->compareValues(
$this->getXmlAsDom($expected),
$this->getXmlAsDom($other)
);
}
/**
......@@ -156,15 +168,12 @@ class EcomDev_PHPUnit_Constraint_Config_Layout
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateLayoutFile($other)
protected function evaluateLayoutFile()
{
$assertion = self::getDesignPackageModel()
->getLayoutFileAssertion($this->_expectedValue, $this->_area, $this->_designPackage, $this->_theme);
$this->setActualValue($assertion['actual']);
$this->_expectedValue = $assertion['expected'];
return $this->_actualValue === $this->_expectedValue;
return $this->compareValues($assertion['expected'], $assertion['actual']);
}
/**
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -99,9 +99,7 @@ class EcomDev_PHPUnit_Constraint_Config_Module
*/
protected function evaluateCodePool($other)
{
$this->setActualValue((string)$other->codePool);
return $this->_actualValue === $this->_expectedValue;
return $this->compareValues($this->_expectedValue, (string)$other->codePool);
}
/**
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -43,7 +43,7 @@ class EcomDev_PHPUnit_Constraint_Config_Node
public function __construct($nodePath, $type, $expectedValue = null)
{
$this->_expectedValueValidation += array(
self::TYPE_EQUALS_STRING => array(true, 'is_string', 'string'),
self::TYPE_EQUALS_STRING => array(true, 'is_scalar', 'scalar'),
self::TYPE_EQUALS_NUMBER => array(true, 'is_numeric', 'numeric'),
self::TYPE_LESS_THAN => array(true, 'is_numeric', 'numeric'),
self::TYPE_GREATER_THAN => array(true, 'is_numeric', 'numeric'),
......@@ -68,7 +68,7 @@ class EcomDev_PHPUnit_Constraint_Config_Node
*/
protected function evaluateEqualsString($other)
{
return (string)$other === $this->_expectedValue;
return $this->compareValues($this->_expectedValue, (string)$other);
}
/**
......@@ -88,7 +88,7 @@ class EcomDev_PHPUnit_Constraint_Config_Node
*/
protected function evaluateEqualsNumber($other)
{
return (float)$other == $this->_expectedValue;
return $this->compareValues($this->_expectedValue, (float)$other);
}
/**
......@@ -171,27 +171,10 @@ class EcomDev_PHPUnit_Constraint_Config_Node
*/
protected function evaluateEqualsXml($other)
{
// Normalize expected XML for matching appropriate xml structure without
// whitespaces, etc
if (!$this->_expectedValue instanceof Varien_Simplexml_Element) {
try {
if ($other instanceof SimpleXMLElement) {
$other = $other->asXML();
}
$expectedXml = new Varien_Simplexml_Element($this->_expectedValue);
} catch (Exception $e) {
throw new RuntimeException(sprintf(
'Expected value is not an xml string for node %s, passed expected value: %s, parsing error: %s',
$this->_nodePath,
PHPUnit_Util_Type::export($this->_expectedValue),
$e->getMessage()
));
}
$expectedValue = $this->getXmlAsDom($this->_expectedValue);
$other = $this->getXmlAsDom($other);
$this->_expectedValue = $expectedXml;
}
return $this->_expectedValue->asNiceXml() == $other->asNiceXml();
return $this->compareValues($expectedValue, $other);
}
......@@ -286,7 +269,7 @@ class EcomDev_PHPUnit_Constraint_Config_Node
*
* @return string
*/
protected function textContainValue()
protected function textContainValues()
{
return sprintf('contains "%s" in comma separated value list',
PHPUnit_Util_Type::export($this->_expectedValue));
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -154,6 +154,7 @@ class EcomDev_PHPUnit_Constraint_Config_Resource_Script
self::FILE_UPGRADE_DATA => array('data', 'upgrade')
);
foreach ($directoryIterator as $entry) {
/* @var $entry SplFileInfo */
// We do not support scheme upgrade scripts with .sql
......@@ -206,6 +207,9 @@ class EcomDev_PHPUnit_Constraint_Config_Resource_Script
*/
protected function getVersionScriptsDiff($versions, $from = null, $to = null, $scriptPrefix = '')
{
usort($versions['install'], array($this, 'compareVersions'));
usort($versions['upgrade'], array($this, 'compareVersions'));
if ($from === null && end($versions['install'])) {
$version = end($versions['install']);
$from = $version['from'];
......@@ -227,7 +231,7 @@ class EcomDev_PHPUnit_Constraint_Config_Resource_Script
$latestVersionFound = null;
if (empty($versions['install']) && $from !== null) {
$expectedVersions[] = sprintf('install-%s.php', $scriptPrefix, $from);
$expectedVersions[] = sprintf('%sinstall-%s.php', $scriptPrefix, $from);
$latestVersionFound = $from;
} elseif ($from !== null) {
foreach ($versions['install'] as $index=>$version) {
......
<?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) 2013 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>
*/
/**
* Controller router configuration constraint
*
*/
class EcomDev_PHPUnit_Constraint_Config_Route
extends EcomDev_PHPUnit_Constraint_Config_Abstract
{
const XML_PATH_ROUTE_NODE = '%s/routers/%s';
const TYPE_MODULE = 'module';
const TYPE_MODULE_ORDER = 'module_order';
const TYPE_ROUTER = 'router';
const TYPE_FRONT_NAME = 'front_name';
/**
* Name of the area for constraint
*
* @var string
*/
protected $_area = null;
/**
* Name of the route for constraint
*
* @var string
*/
protected $_routeName = null;
/**
* Constraint for evaluation of module config node
*
* @param string $area
* @param string $route
* @param string $type
* @param mixed $expectedValue
*/
public function __construct($area, $route, $type, $expectedValue)
{
$this->_area = $area;
$this->_routeName = $route;
$this->_expectedValueValidation += array(
self::TYPE_MODULE => array(true, 'is_string', 'string'),
self::TYPE_MODULE_ORDER => array(true, 'is_array', 'array'),
self::TYPE_ROUTER => array(true, 'is_string', 'string'),
self::TYPE_FRONT_NAME => array(true, 'is_string', 'string')
);
$this->_typesWithDiff[] = self::TYPE_MODULE;
$this->_typesWithDiff[] = self::TYPE_MODULE_ORDER;
$this->_typesWithDiff[] = self::TYPE_FRONT_NAME;
$this->_typesWithDiff[] = self::TYPE_ROUTER;
parent::__construct(
sprintf(self::XML_PATH_ROUTE_NODE, $this->_area, $this->_routeName),
$type,
$expectedValue
);
}
/**
* Evaluates that module is added to route for controllers processing
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateModule($other)
{
if (!isset($other->args)
|| (!isset($other->args->module) && !isset($other->args->modules))) {
$this->_expectedValue = (array) $this->_expectedValue;
$this->setActualValue(array());
return false;
}
$currentModules = $this->getModules($other->args);
// Save actual value
$this->setActualValue($currentModules);
// Will add diff to module structure
if (!in_array($this->_expectedValue, $currentModules)) {
$currentModules[] = $this->_expectedValue;
}
$this->_expectedValue = $currentModules;
return $this->_actualValue === $this->_expectedValue;
}
/**
* Text representation of class alias constraint
*
* @return string
*/
protected function textModule()
{
return 'contains expected module';
}
/**
* Evaluates that modules are added to route for controllers processing
* in particular order
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateModuleOrder($other)
{
if ((!isset($other->args->module) && !isset($other->args->modules))) {
$this->setActualValue(array());
return false;
}
$currentModules = $this->getModules($other->args);
// Save actual value
$this->setActualValue($currentModules);
$previousIndex = false;
foreach ($this->_expectedValue as $index => $expectedValue) {
if ($previousIndex === false) {
if (!in_array($expectedValue, $currentModules)
&& (!isset($this->_expectedValue[$index+1])
|| !in_array($this->_expectedValue[$index+1], $currentModules))) {
$currentModules[] = $expectedValue;
} elseif (!in_array($expectedValue, $currentModules)) {
// Add new item before next one
array_splice($currentModules,
array_search($this->_expectedValue[$index+1], $currentModules),
0, array($expectedValue));
}
} else {
$previousValue = $this->_expectedValue[$previousIndex];
$isInArray = in_array($expectedValue, $currentModules);
$isAfter = $isInArray && array_search($previousValue, $currentModules) >
array_search($expectedValue, $currentModules);
if ($isInArray && $isAfter) {
continue;
} elseif (!$isAfter) {
// Remove current item from modules
array_splice($currentModules, array_search($expectedValue, $currentModules), 1);
}
// Add new item after previous one
array_splice($currentModules,
array_search($previousValue, $currentModules)+1,
0, array($expectedValue));
}
$previousIndex = $index;
}
$this->_expectedValue = $currentModules;
return $this->_actualValue === $this->_expectedValue;
}
/**
* Text representation of class alias constraint
*
* @return string
*/
protected function textModuleOrder()
{
return 'contains modules in expected order';
}
/**
* Evaluates that route is added to expected router
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateRouter($other)
{
$this->setActualValue((string)$other->use);
return $this->_actualValue === $this->_expectedValue;
}
/**
* Text representation of class alias constraint
*
* @return string
*/
protected function textRouter()
{
return 'is specified for expected router';
}
/**
* Evaluates that route is added to expected router
*
* @param Varien_Simplexml_Element $other
* @return boolean
*/
protected function evaluateFrontName($other)
{
$frontName = '';
if (isset($other->args->frontName)) {
$frontName = (string)$other->args->frontName;
}
$this->setActualValue($frontName);
return $this->_actualValue === $this->_expectedValue;
}
/**
* Text representation of class alias constraint
*
* @return string
*/
protected function textFrontName()
{
return 'is specified for the same front name as expected';
}
/**
* Returns sorted list of modules from args node
*
* @param Varien_Simplexml_Element $argsNode
* @return array
*/
protected function getModules(Varien_Simplexml_Element $argsNode)
{
$modules = array();
if (isset($argsNode->module)) {
$modules[] = (string)$argsNode->module;
}
if (isset($argsNode->modules)) {
// Repeats logic in core router
foreach ($argsNode->modules->children() as $module) {
if ((string)$module) {
if ($before = $module->getAttribute('before')) {
$position = array_search($before, $modules);
if ($position === false) {
$position = 0;
}
array_splice($modules, $position, 0, (string)$module);
} elseif ($after = $module->getAttribute('after')) {
$position = array_search($after, $modules);
if ($position === false) {
$position = count($modules);
}
array_splice($modules, $position+1, 0, (string)$module);
} else {
$modules[] = (string)$module;
}
}
}
}
return $modules;
}
/**
* Custom failure description for showing config related errors
* (non-PHPdoc)
* @see PHPUnit_Framework_Constraint::customFailureDescription()
*/
protected function customFailureDescription($other)
{
return sprintf(
'controller route %s for %s area %s.',
$this->_routeName,
$this->_area,
$this->toString()
);
}
}
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -103,11 +103,14 @@ class EcomDev_PHPUnit_Constraint_Json extends EcomDev_PHPUnit_Constraint_Abstrac
$decodedJson = Zend_Json::decode($other);
$this->setActualValue($decodedJson);
$intersection = array_intersect_assoc(
$this->_actualValue,
$this->_expectedValue
$intersection = array_intersect(
array_keys($this->_actualValue),
array_keys($this->_expectedValue)
);
// @todo make it more recursive
switch ($this->_matchType) {
case self::MATCH_OR:
$matched = !empty($intersection);
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -263,7 +263,7 @@ class EcomDev_PHPUnit_Constraint_Layout_Block extends EcomDev_PHPUnit_Constraint
}
$this->setActualValue($blockInfo['class']);
$actualReflection = EcomDev_Utils_Reflection::getRelflection($this->_actualValue);
$actualReflection = EcomDev_Utils_Reflection::getReflection($this->_actualValue);
return $this->_actualValue === $this->_expectedValue
|| $actualReflection->isSubclassOf($this->_expectedValue);
}
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......
......@@ -11,7 +11,7 @@
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2012 EcomDev BV (http://www.ecomdev.org)
* @copyright Copyright (c) 2013 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>
*/
......@@ -31,6 +31,7 @@ class EcomDev_Utils_Reflection
* @param string|object $object class name
* @param string $property
* @param mixed $value
* @throws RuntimeException
*/
public static function setRestrictedPropertyValue($object, $property, $value)
{
......@@ -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');
}
$reflectionObject = self::getRelflection($object);
$reflectionObject = self::getReflection($object);
$reflectionProperty = $reflectionObject->getProperty($property);
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue((is_string($object) ? null : $object), $value);
......@@ -49,6 +50,7 @@ class EcomDev_Utils_Reflection
*
* @param string|object $object class name
* @param array $properties
* @throws RuntimeException
*/
public static function setRestrictedPropertyValues($object, array $properties)
{
......@@ -67,6 +69,7 @@ class EcomDev_Utils_Reflection
* @param string|object $object class name
* @param string $property
* @return mixed
* @throws RuntimeException
*/
public static function getRestrictedPropertyValue($object, $property)
{
......@@ -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');
}
$reflectionObject = self::getRelflection($object);
$reflectionObject = self::getReflection($object);
$reflectionProperty = $reflectionObject->getProperty($property);
$reflectionProperty->setAccessible(true);
return $reflectionProperty->getValue((is_string($object) ? null : $object));
......@@ -88,6 +91,7 @@ class EcomDev_Utils_Reflection
* @param string $method
* @param array $args
* @return mixed
* @throws RuntimeException
*/
public static function invokeRestrictedMethod($object, $method, $args = array())
{
......@@ -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');
}
$reflectionObject = self::getRelflection($object);
$reflectionObject = self::getReflection($object);
$reflectionMethod = $reflectionObject->getMethod($method);
$reflectionMethod->setAccessible(true);
......@@ -111,8 +115,21 @@ class EcomDev_Utils_Reflection
*
* @param string|object $object
* @return ReflectionClass|ReflectionObject
* @deprecated since 0.3.0 deprecated because of typo
*/
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 (is_string($object) && class_exists($object)) {
......
# EcomDev_PHPUnit definition
UnitTests.php UnitTests.php
app/etc/modules/EcomDev_PHPUnit.xml app/etc/modules/EcomDev_PHPUnit.xml
app/code/community/EcomDev/PHPUnit app/code/community/EcomDev/PHPUnit
lib/EcomDev/PHPUnit lib/EcomDev/PHPUnit
lib/EcomDev/Utils lib/EcomDev/Utils
app/etc/modules/EcomDev_*.xml app/etc/modules/
app/code/community/EcomDev/* app/code/community/EcomDev/
lib/EcomDev/* lib/EcomDev/
lib/Spyc lib/Spyc
lib/vfsStream lib/vfsStream
shell/ecomdev-phpunit-install.php shell/ecomdev-phpunit-install.php
# Copy local.xml.phpunit if it doesn't already exist
@shell \
LOCALXML=app/etc/local.xml.phpunit; \
if [ ! -f $PROJECT/$LOCALXML ]; then \
cp $MODULE/$LOCALXML $PROJECT/$LOCALXML; \
fi
# Copy phpunit.xml if it doesn't already exist
@shell \
PHPUNITXML=phpunit.xml.dist; \
if [ ! -f $PROJECT/$LOCALXML ]; then \
cp $MODULE/$PHPUNITXML $PROJECT/$PHPUNITXML; \
fi
# Run shell installer
@shell cd $PROJECT/shell && php -f ecomdev-phpunit-install.php -- --module $MODULE --project $PROJECT
......@@ -10,12 +10,14 @@
stopOnIncomplete="false"
stopOnSkipped="false"
strict="false"
verbose="false">
<testsuites>
<testsuite name="Magento Unit Tests">
<file>UnitTests.php</file>
</testsuite>
</testsuites>
verbose="false"
bootstrap="app/code/community/EcomDev/PHPUnit/bootstrap.php">
<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>
<blacklist>
<!-- Exclude Magento Core files from code coverage -->
......@@ -28,7 +30,7 @@
<!-- Exclude Mage.php file from code coverage -->
<file>app/Mage.php</file>
<!-- Exclude template files -->
<directory suffix=".phtml">app/code/design</directory>
<directory suffix=".phtml">app/design</directory>
<!-- Exclude Varien & Zend libraries -->
<directory suffix=".php">lib/Varien</directory>
<directory suffix=".php">lib/Zend</directory>
......
<?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) 2013 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>
*/
require_once 'abstract.php';
/**
* Shell script for autoinstalling of required files for phpunit extension
*
*
*/
class EcomDev_PHPUnit_Install extends Mage_Shell_Abstract
{
const FILE_LOCAL_XML = 'app/etc/local.xml.phpunit';
const FILE_PHPUNIT_XML = 'phpunit.xml.dist';
const OLD_FILE_MATCH = '/\\<file\\>UnitTests.php\\<\\/file\\>/';
/**
* This script doesn't need initialization of Magento
*
* @var bool
*/
protected $_includeMage = false;
/**
* Runs scripts itself
*/
public function run()
{
if (!$this->getArg('module') || !$this->getArg('project')) {
die($this->usageHelp());
}
$this->_copyLocalXml();
$this->_copyPHPUnitXml();
$this->_cleanCache();
}
/**
* Copies local XML file from phpunit extension folder
*
*/
protected function _copyLocalXml()
{
if (!file_exists($this->getArg('project') . DIRECTORY_SEPARATOR . self::FILE_LOCAL_XML)) {
copy($this->getArg('module') . DIRECTORY_SEPARATOR . self::FILE_LOCAL_XML,
$this->getArg('project') . DIRECTORY_SEPARATOR . self::FILE_LOCAL_XML);
}
}
/**
* Checks existence of phpunit.xml.dist file, if file is outdated,
* it just replaces the content of it.
*
*/
protected function _copyPHPUnitXml()
{
if (!file_exists($this->getArg('project') . DIRECTORY_SEPARATOR . self::FILE_PHPUNIT_XML)
|| preg_match(self::OLD_FILE_MATCH,
file_get_contents($this->getArg('project') . DIRECTORY_SEPARATOR . self::FILE_PHPUNIT_XML))) {
copy($this->getArg('module') . 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