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

Commit 03169b5b authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

+ PHPUnit test suite initial version

parent 707b289f
<?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');
}
if (!Mage::isInstalled()) {
exit('Magento Unit Tests can be runned only on installed version');
}
Mage::app('admin');
Mage::getConfig()->init();
class UnitTests extends EcomDev_PHPUnit_Test_Suite
{
}
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Application model for phpunit tests
*
*/
class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
{
// Run types constants,
// Don't know why
// they are not defined in core application
const RUN_TYPE_STORE = 'store';
const RUN_TYPE_WEBSITE = 'website';
const RUN_TYPE_GROUP = 'group';
// Admin store code
const ADMIN_STORE_CODE = 'admin';
/**
* Old configuration model to be returned back
* after unit tests are finished
*
* @var Mage_Core_Model_Config
*/
protected static $_oldConfig = null;
/**
* Old application model to be returned back
* after unit tests are finished
*
* @var Mage_Core_Model_App
*/
protected static $_oldApplication = null;
/**
* Old event collection to be returned back
* after the unit tests are finished
*
* @var Varien_Event_Collection
*/
protected static $_oldEventCollection = null;
/**
* Configuration model class name for unit tests
*
* @var string
*/
protected static $_configClass = 'EcomDev_PHPUnit_Model_Config';
/**
* Configuration model class name for unit tests
*
* @var string
*/
protected static $_eventCollectionClass = 'Varien_Event_Collection';
/**
* Configuration model class name for unit tests
*
* @var string
*/
protected static $_cacheClass = 'EcomDev_PHPUnit_Model_Cache';
/**
* This method replaces application, event and config objects
* in Mage to perform unit tests in separate Magento steam
*
*/
public static function applyTestScope()
{
// Save old environment variables
self::$_oldApplication = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_app');
self::$_oldConfig = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_config');
self::$_oldEventCollection = EcomDev_Utils_Reflection::getRestrictedPropertyValue('Mage', '_events');
$resource = Mage::getSingleton('core/resource');
// Setting environment variables for unit tests
EcomDev_Utils_Reflection::setRestrictedPropertyValue('Mage', '_config', new self::$_configClass);
EcomDev_Utils_Reflection::setRestrictedPropertyValue('Mage', '_app', new self);
EcomDev_Utils_Reflection::setRestrictedPropertyValue('Mage', '_events', new self::$_eventCollectionClass);
EcomDev_Utils_Reflection::setRestrictedPropertyValue($resource, '_connections', array());
// All unit tests will be runned in admin scope, to get rid of frontend restrictions
Mage::app()->initTest();
}
/**
* Initializes test scope for PHPUnit
*
* @return EcomDev_PHPUnit_Model_App
*/
public function initTest()
{
$this->_config = Mage::getConfig();
$this->_config->setOptions($options);
$this->_initBaseConfig();
$this->_initCache();
$this->getCache()->clean();
// Init modules runs install proccess for table structures,
// It is required for setting up proper setup script
$this->_initModules();
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
if ($this->_config->isLocalConfigLoaded()) {
$this->_initCurrentStore(self::ADMIN_STORE_CODE, self::RUN_TYPE_STORE);
$this->_initRequest();
Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
}
return $this;
}
/**
* Discard test scope for application, returns all the objects from live version
*
*/
public static function discardTestScope()
{
// Setting environment variables for unit tests
EcomDev_Utils_Reflection::setRestrictedPropertyValue('Mage', '_app', self::$_oldApplication);
EcomDev_Utils_Reflection::setRestrictedPropertyValue('Mage', '_config', self::$_oldConfig);
EcomDev_Utils_Reflection::setRestrictedPropertyValue('Mage', '_events', self::$_oldEventCollection);
$resource = Mage::getSingleton('core/resource');
EcomDev_Utils_Reflection::setRestrictedPropertyValue($resource, '_connections', array());
}
/**
* We will not use cache for UnitTests
*
* @return boolean
*/
public function useCache($type=null)
{
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) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Configution model extended to make unit tests to be available
* at separate configuration scope
*
*/
class EcomDev_PHPUnit_Model_Config extends Mage_Core_Model_Config
{
/**
* Loads additional configuration for unit tests
* (non-PHPdoc)
* @see Mage_Core_Model_Config::loadBase()
*/
public function loadBase()
{
parent::loadBase();
$this->_loadTestCacheConfig();
return $this;
}
/**
* (non-PHPdoc)
* @see Mage_Core_Model_Config::loadModules()
*/
public function loadModules()
{
parent::loadModules();
$this->_loadTestConfig();
$this->_loadTestCacheConfig();
return $this;
}
/**
* Loads local.xml.phpunit file
* for overriding DB credentials
*
* @return EcomDev_PHPUnit_Model_Config
*/
protected function _loadTestConfig()
{
$merge = clone $this->_prototype;
if ($merge->loadFile($this->_getLocalXmlForTest())) {
$this->_checkDbCredentialForDuplicate($this, $merge);
$this->extend($merge);
} else {
throw new Exception('Unable to load local.xml.phpunit');
}
return $this;
}
/**
* Loads cache configuration for PHPUnit tests scope
*
* @return EcomDev_PHPUnit_Model_Config
*/
protected function _loadTestCacheConfig()
{
// Cache beckend initialization for unit tests,
// because it should be separate from live one
$this->setNode('global/cache/backend', 'file');
$this->getOptions()->setData('cache_dir', $this->getVarDir() . DS . 'phpunit.cache');
$this->getOptions()->setData('session_dir', $this->getVarDir() . DS . 'phpunit.session');
return $this;
}
/**
* Checks DB credentials for phpunit test case.
* They shouldn't be the same as live ones.
*
* @param Mage_Core_Model_Config_Base $original
* @param Mage_Core_Model_Config_Base $test
* @return EcomDev_PHPUnit_Model_Config
* @throws RuntimeException
*/
protected function _checkDbCredentialForDuplicate($original, $test)
{
$originalDbName = (string) $original->getNode('global/resources/default_setup/connection/dbname');
$testDbName = (string) $test->getNode('global/resources/default_setup/connection/dbname');
if ($originalDbName == $testDbName) {
throw new RuntimeException('Test DB cannot be the same as the live one');
}
return $this;
}
/**
* Retrieves local.xml file path for tests,
* If it is not found, method will rise an exception
*
* @return string
* @throws RuntimeException
*/
protected function _getLocalXmlForTest()
{
$filePath = $this->getOptions()->getEtcDir() . DS . 'local.xml.phpunit';
if (!file_exists($filePath)) {
throw new RuntimeException('There is no local.xml.phpunit file');
}
return $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) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
// Loading Spyc yaml parser,
// becuase Symfony component is not working propertly with nested
require_once 'Spyc/spyc.php';
/**
* Fixture model for Magento unit tests
*
* Created for operations with different fixture types
*
*/
class EcomDev_PHPUnit_Model_Fixture extends Mage_Core_Model_Abstract
{
/**
* Fixtures array, contains config,
* table and eav keys.
* Each of them loads data into its area.
*
* @example
* array(
* 'config' => array(
* 'node/path' => 'value'
* ),
* 'table' => array(
* 'tablename' => array(
* array(
* 'column1' => 'value'
* 'column2' => 'value'
* 'column3' => 'value'
* ), // row 1
* array(
* 'column1' => 'value'
* 'column2' => 'value'
* 'column3' => 'value'
* ) // row 2
* )
* )
*
* )
*
* @var array
*/
protected $_fixture = array();
/**
* Associative array of configuration values that was changed by fixture,
* it is used to preserve
*
*/
protected $_originalConfiguration = array();
/**
* Model constuctor, just defines wich resource model to use
* (non-PHPdoc)
* @see Varien_Object::_construct()
*/
protected function _construct()
{
$this->_init('ecomdev_phpunit/fixture');
}
/**
* Load YAML file
*
* @param string $filePath
* @return EcomDev_PHPUnit_Model_Fixture
* @throws InvalidArgumentException if file is not a valid YAML file
*/
public function loadYaml($filePath)
{
$data = Spyc::YAMLLoad($filePath);
if (empty($this->_fixture)) {
$this->_fixture = $data;
} else {
$this->_fixture = array_merge_recursive($this->_fixture, $data);
}
return $this;
}
/**
* Applies loaded fixture
*
* @return EcomDev_PHPUnit_Model_Fixture
*/
public function apply()
{
$reflection = EcomDev_Utils_Reflection::getRelflection($this);
foreach ($this->_fixture as $part => $data) {
$method = '_apply' . uc_words($part, '', '_');
if ($reflection->hasMethod($method)) {
$this->$method($data);
}
}
return $this;
}
/**
* Reverts environment to previous state
*
* @return EcomDev_PHPUnit_Model_Fixture
*/
public function discard()
{
$reflection = EcomDev_Utils_Reflection::getRelflection($this);
foreach ($this->_fixture as $part => $data) {
$method = '_discard' . uc_words($part, '', '_');
if ($reflection->hasMethod($method)) {
$this->$method($data);
}
}
$this->_fixture = array();
}
/**
* Applies fixture configuration values into Mage_Core_Model_Config
*
* @param array $configuration
* @return EcomDev_PHPUnit_Model_Fixture
*/
protected function _applyConfig($configuration)
{
if (!is_array($configuration)) {
throw new InvalidArgumentException('Configuration part should be an associative list');
}
foreach ($configuration as $path => $value) {
$this->_originalConfiguration[$path] = Mage::getConfig()->getNode($path);
Mage::getConfig()->setNode($path, $value);
}
return $this;
}
/**
* Reverts fixture configuration values in Mage_Core_Model_Config
*
* @return EcomDev_PHPUnit_Model_Fixture
*/
protected function _discardConfig()
{
foreach ($this->_originalConfiguration as $path => $value) {
Mage::getConfig()->setNode($path, $value);
}
$this->_originalConfiguration = array();
return $this;
}
/**
* Applies table data into test database
*
* @param array $tables
* @return EcomDev_PHPUnit_Model_Fixture
*/
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'
);
}
foreach ($tables as $tableEntity => $data) {
$this->getResource()->cleanTable($tableEntity);
$this->getResource()->loadTableData($tableEntity, $data);
}
}
/**
* Removes table data from test data base
*
* @param array $tables
* @return EcomDev_PHPUnit_Model_Fixture
*/
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'
);
}
foreach ($tables as $tableEntity => $data) {
$this->getResource()->cleanTable($tableEntity);
}
}
/**
* @todo Create Implementation for EAV models
*/
/**
* @todo Create Implementation for Websites/Stores/Groups
*/
}
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Fixture resource model.
*
* Created for direct operations with DB.
*
*/
class EcomDev_PHPUnit_Model_Mysql4_Fixture extends Mage_Core_Model_Mysql4_Abstract
{
protected function _construct()
{
$this->_setResource('ecomdev_phpunit');
}
/**
* Cleans table in test database
*
* @param string $tableEntity
* @return EcomDev_PHPUnit_Model_Mysql4_Fixture
*/
public function cleanTable($tableEntity)
{
$this->_getWriteAdapter()
->truncate($this->getTable($tableEntity));
return $this;
}
/**
* Loads multiple data rows into table
*
* @param string $tableEntity
* @param array $tableData
*/
public function loadTableData($tableEntity, $tableData)
{
$this->_getWriteAdapter()->insertMultiple(
$this->getTable($tableEntity),
$tableData
);
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) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
// Loading Spyc yaml parser,
// becuase Symfony component is not working propertly with nested associations
require_once 'Spyc/spyc.php';
/**
* Basic test case class
*
*
*/
abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
{
/**
* The expectations for current test are loaded here
*
* @var Varien_Object|null
*/
protected $_expectations = null;
/**
* Loads expectations for current test case
*
* @throws RuntimeException if no expectation was found
* @return Varien_Object
*/
protected function _getExpectations()
{
if ($this->_expectations === null) {
$annotations = $this->getAnnotations();
if (isset($annotations['method']['loadExpectation'])) {
// Load expectation by annotations
$expectations = array();
foreach ($annotations['method']['loadExpectation'] as $expectation) {
if (empty($expectation)) {
$expectation = null;
}
$expectationFile = $this->_getYamlFilePath('expectations', $expectation);
if ($expectationFile) {
$expectations = array_merge_recursive(
$expectations, Spyc::YAMLLoad($expectationFile)
);
} else {
$text = 'There was no expectation defined for current test case';
if ($expectation) {
$text = sprintf('Cannot load expectation %s', $expectation);
}
throw new RuntimeException($test);
}
}
} else {
// Load expectations by test name
$expectationFile = $this->_getYamlFilePath('expectations');
if ($expectationFile) {
$expectations = Spyc::YAMLLoad($expectationFile);
} else {
throw new RuntimeException('There was no expectation defined for current test case');
}
}
$this->_expectations = new Varien_Object($expectations);
}
return $this->_expectations;
}
/**
* Retrieves fixture model singleton
*
* @return EcomDev_PHPUnit_Model_Fixture
*/
protected function _getFixture()
{
return Mage::getSingleton('ecomdev_phpunit/fixture');
}
/**
* Loads YAML file from directory inside of the unit test class
* Enter description here ...
*
* @param string $type type of YAML data (fixtures,expectations,dataproviders)
* @param string|null $name the file name for loading, if equals to null,
* the current test name will be used
* @return string|boolean
*/
protected function _getYamlFilePath($type, $name = null)
{
if ($name === null) {
$name = $this->getName(false);
}
if (strrpos($name, '.yaml') !== strlen($name) - 5) {
$name .= '.yaml';
}
$classFileObject = new SplFileInfo(
EcomDev_Utils_Reflection::getRelflection($this)->getFileName()
);
$filePath = $classFileObject->getPath() . DS
. $classFileObject->getBasename('.php') . DS
. $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()
{
$annotations = $this->getAnnotations();
if (isset($annotations['method']['loadFixture'])) {
foreach ($annotations['method']['loadFixture'] as $fixture) {
if (empty($fixture)) {
$fixture = null;
}
$filePath = $this->_getYamlFilePath('fixtures', $fixture);
if (!$filePath) {
throw new RuntimeException('Unable to load fixture for test');
}
$this->_getFixture()->loadYaml($filePath);
}
}
$this->_getFixture()->apply();
parent::setUp();
}
/**
* Implements default data provider functionality,
* returns array data loaded from Yaml file with the same name as test method
*
* @return array
*/
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);
}
/**
* Performs a clean up after a particular test was run
* (non-PHPdoc)
* @see PHPUnit_Framework_TestCase::tearDown()
*/
protected function tearDown()
{
$this->_expectations = null; // Clear expectation values
$this->_getFixture()->discard(); // Clear applied fixture
parent::tearDown();
}
}
\ 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) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Test suite for Magento
*
* It discovers all test cases in modules
* if they were added to 'phpunit/suite/modules' configuration node
*
*/
class EcomDev_PHPUnit_Test_Suite extends PHPUnit_Framework_TestSuite
{
// Configuration path constants
const XML_PATH_UNIT_TEST_GROUPS = 'phpunit/suite/groups';
const XML_PATH_UNIT_TEST_MODULES = 'phpunit/suite/modules';
const XML_PATH_UNIT_TEST_APP = 'phpunit/suite/app';
/**
* 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
*
* @return PHPUnit_Framework_TestSuite
*/
public static function suite()
{
$groups = Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_GROUPS);
$modules = Mage::getConfig()->getNode(self::XML_PATH_UNIT_TEST_MODULES);
$suite = new self('Magento Test Suite');
// Walk through different groups in modules for finding test cases
foreach ($groups->children() as $group) {
foreach ($modules->children() as $module) {
$realModule = Mage::getConfig()->getNode('modules/' . $module->getName());
if (!$realModule || !$realModule->is('active')) {
$suite->addTest(self::warning('There is no module with name: ' . $module->getName()));
continue;
}
$moduleCodeDir = Mage::getBaseDir('code') . DS . (string) $realModule->codePool;
$searchPath = Mage::getModuleDir('', $module->getName()) . DS . 'Test' . DS . (string) $group;
if (!is_dir($searchPath)) {
continue;
}
$directoryIterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($searchPath)
);
$currentGroups = array(
$group->getName(),
$module->getName()
);
foreach ($directoryIterator as $fileObject) {
/* @var $fileObject SplFileObject */
// Skip entry if it is not a php file
if (!$fileObject->isFile() || $fileObject->getBasename('.php') === $fileObject->getBasename()) {
continue;
}
$classPath = substr($fileObject->getPath() . DS . $fileObject->getBasename('.php'), strlen($moduleCodeDir));
$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 (class_exists($className, true)) {
$reflectionClass = EcomDev_Utils_Reflection::getRelflection($className);
if (!$reflectionClass->isSubclassOf('EcomDev_PHPUnit_Test_Case')) {
continue;
}
$suite->addTest(new PHPUnit_Framework_TestSuite($reflectionClass), $currentGroups);
}
}
}
}
if (!$suite->count()) {
$suite->addTest(self::warning('There were no test cases for the current run'));
}
return $suite;
}
}
<?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) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
-->
<config>
<modules>
<EcomDev_PHPUnit>
<version>0.1.0</version>
</EcomDev_PHPUnit>
</modules>
<global>
<models>
<ecomdev_phpunit>
<class>EcomDev_PHPUnit_Model</class>
<resourceModel>ecomdev_phpunit_mysql4</resourceModel>
</ecomdev_phpunit>
<ecomdev_phpunit_mysql4>
<class>EcomDev_PHPUnit_Model_Mysql4</class>
</ecomdev_phpunit_mysql4>
</models>
</global>
<phpunit>
<suite>
<!-- The names of directories inside Test for recognizion of tests per group -->
<groups>
<models>Model</models>
<helpers>Helper</helpers>
<blocks>Block</blocks>
</groups>
<!-- Application model class name for running tests -->
<app>EcomDev_PHPUnit_Model_App</app>
<modules>
<!-- Place your module name in your module config.xml
For adding it to test suite -->
<!-- Example:
<Namespace_MyModule />
-->
</modules>
</suite>
</phpunit>
</config>
<?xml version="1.0"?>
<config>
<global>
<resources>
<default_setup>
<connection>
<dbname><![CDATA[magento_unit_tests]]></dbname>
</connection>
</default_setup>
</resources>
</global>
</config>
<?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) 2010 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
-->
<config>
<modules>
<EcomDev_PHPUnit>
<codePool>community</codePool>
<active>true</active>
</EcomDev_PHPUnit>
</modules>
</config>
\ No newline at end of file
<?php
class EcomDev_Utils_Reflection
{
/**
* Cache of reflection objects
*
* @var array
*/
protected static $_reflectionCache = array();
/**
* Sets protected or private property value
*
* @param string|object $object class name
* @param string $property
* @param mixed $value
*/
public static function setRestrictedPropertyValue($object, $property, $value)
{
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
throw new RuntimeException('For setting of restricted properties via Reflection, PHP version should be 5.3.0 or later');
}
$reflectionObject = self::getRelflection($object);
$reflectionProperty = $reflectionObject->getProperty($property);
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue((is_string($object) ? null : $object), $value);
}
/**
* Gets protected or private property value
*
* @param string|object $object class name
* @param string $property
* @return mixed
*/
public static function getRestrictedPropertyValue($object, $property)
{
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
throw new RuntimeException('For getting of restricted properties via Reflection, PHP version should be 5.3.0 or later');
}
$reflectionObject = self::getRelflection($object);
$reflectionProperty = $reflectionObject->getProperty($property);
$reflectionProperty->setAccessible(true);
return $reflectionProperty->getValue((is_string($object) ? null : $object));
}
/**
* Calls private or protected method
*
* @param string|object $object
* @param string $method
* @param array $args
* @return mixed
*/
public static function invokeRestrictedMethod($object, $method, $args = array())
{
if (version_compare(PHP_VERSION, '5.3.2', '<')) {
throw new RuntimeException('For invoking restricted methods via Reflection, PHP version should be 5.3.2 or later');
}
$reflectionObject = self::getRelflection($object);
$reflectionMethod = $reflectionObject->getMethod($method);
$reflectionMethod->setAccessible(true);
if (!empty($args)) {
return $reflectionMethod->invokeArgs($reflectionObject, $args);
}
return $reflectionMethod->invoke((is_string($object) ? null : $object));
}
/**
* Returns reflection object from instance or class name
*
* @param string|object $object
* @return ReflectionClass|ReflectionObject
*/
public static function getRelflection($object)
{
// If object is a class name
if (is_string($object) && class_exists($object)) {
if (isset(self::$_reflectionCache[$object])) {
return self::$_reflectionCache[$object];
}
$reflection = new ReflectionClass($object);
self::$_reflectionCache[$object] = $reflection;
return $reflection;
}
// If object is an instance of a class
elseif (is_object($object)) {
$objectHash = spl_object_hash($object);
if (isset(self::$_reflectionCache[$objectHash])) {
return self::$_reflectionCache[$objectHash];
}
$reflection = new ReflectionClass($object);
self::$_reflectionCache[$objectHash] = $reflection;
return $reflection;
}
// In case of invalid argument
else {
throw new InvalidArgumentException('$object should be a valid class name or object instance');
}
}
}
\ No newline at end of file
This diff is collapsed.
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