/** * Contructor adds test groups defined on global level * and adds additional logic for test names retrieval * * (non-PHPdoc) * @see PHPUnit_Framework_TestSuite::__construct() */ public function __construct($theClass = '', $groups = array()) { if (!$theClass instanceof ReflectionClass) { $theClass = Mage_Utils_Reflection::getRelflection($theClass); } // Check annotations for test case name $annotations = PHPUnit_Util_Test::parseTestMethodAnnotations($theClass->getName()); if (isset($annotations['name'])) { $this->suiteName = $annotations['name']; } // Creates all test instances parent::__construct($theClass); // Just sort-out them by our internal groups foreach ($groups as $group) { $this->groups[$group] = $this->tests(); } foreach ($this->tests() as $test) { if ($test instanceof PHPUnit_Framework_TestSuite) { /* @todo * Post an issue into PHPUnit bugtracker for * impossiblity for specifying group by parent test case * Becuase it is a very dirty hack :( **/ $testGroups = array(); foreach ($groups as $group) { $testGroups[$group] = $test->tests(); } Mage_Utils_Reflection::setRestrictedPropertyValue($test, 'groups', $testGroups); } } // Remove ungrouped tests group, if it exists if (isset($this->groups[self::NO_GROUP_KEYWORD])) { unset($this->groups[self::NO_GROUP_KEYWORD]); } }
/** * Abstract cnstraint constructor, * provides unified interface for working with multiple types of evalation * * @param string $type * @param mixed $expectedValue */ public function __construct($type, $expectedValue = null) { $reflection = Mage_Utils_Reflection::getRelflection(get_class($this)); $types = array(); foreach ($reflection->getConstants() as $name => $constant) { if (strpos($name, 'TYPE_') === 0) { $types[] = $constant; } } if (empty($type) || !is_string($type) || !in_array($type, $types)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string', $type); } if (isset($this->_expectedValueValidation[$type])) { $expectedValueType = isset($this->_expectedValueValidation[$type][2]) ? isset($this->_expectedValueValidation[$type][2]) : ''; // Mandatory check if (isset($this->_expectedValueValidation[$type][0]) && $this->_expectedValueValidation[$type][0] && $expectedValue === null) { throw PHPUnit_Util_InvalidArgumentHelper::factory(2, $expectedValueType, $expectedValue); } // Type check if (isset($this->_expectedValueValidation[$type][1]) && $expectedValue !== null && !$this->_expectedValueValidation[$type][1]($expectedValue)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(2, $expectedValueType, $expectedValue); } } $this->_type = $type; $this->_expectedValue = $expectedValue; }
/** * Loads test cases from search path, * Will return cached result * * @param string $searchPath path for searching files with tests * @param string $moduleCodeDir path where the module files are placed (e.g. app/code/local), * used for determining the class name */ protected static function _loadTestCases($searchPath, $moduleCodeDir) { if (Mage::app()->useCache(self::CACHE_TYPE)) { $cachedTestCases = Mage::app()->loadCache(self::CACHE_TYPE . md5($searchPath)); if ($cachedTestCases) { return unserialize($cachedTestCases); } } $testCases = array(); $directoryIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($searchPath)); foreach ($directoryIterator as $fileObject) { /* @var $fileObject SplFileObject */ // Skip entry if it is not a php file if (!$fileObject->isFile() && !$fileObject->isLink() || $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 Mage_PHPUnit_Unit_Case if (class_exists($className, true)) { $reflectionClass = Mage_Utils_Reflection::getRelflection($className); if (!$reflectionClass->isSubclassOf('Mage_Test_Unit_Case') || $reflectionClass->isAbstract()) { continue; } $testCases[] = $className; } } if (Mage::app()->useCache(self::CACHE_TYPE)) { Mage::app()->saveCache(serialize($testCases), self::CACHE_TYPE . md5($searchPath), array(self::CACHE_TAG)); } return $testCases; }
/** * Loads YAML file from directory inside of the unit test class or * the directory inside the module directory if name is prefixed with ~/ * or from another module if name is prefixed with ~My_Module/ * * @param string $className class name for looking fixture files * @param string $type type of YAML data (fixtures,expectations,dataproviders) * @param string $name the file name for loading * @return string|boolean */ public static function getYamlFilePathByClass($className, $type, $name) { if (strrpos($name, '.yaml') !== strlen($name) - 5) { $name .= '.yaml'; } $classFileObject = new SplFileInfo(Mage_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; } else { $filePath = $classFileObject->getPath() . DS . $classFileObject->getBasename('.php') . DS; } $filePath .= $type . DS . $name; if (file_exists($filePath)) { return $filePath; } return false; }
/** * Evaluates that layout block is an instance of expected class/interface * * @param Mage_PHPUnit_Constraint_Layout_Logger_Interface $other * @return boolean */ protected function evaluateInstanceOf($other) { $blockInfo = $other->findFirst(self::ACTION_BLOCK_CREATED, $this->_blockName); if ($blockInfo === false) { $this->setActualValue(false); return false; } $this->setActualValue($blockInfo['class']); $actualReflection = Mage_Utils_Reflection::getRelflection($this->_actualValue); return $this->_actualValue === $this->_expectedValue || $actualReflection->isSubclassOf($this->_expectedValue); }
/** * Returns class name from configuration path, * If $interface is specified, then it additionally checks it for implementation * * * @param string $configPath * @param string $interface * @return string */ protected function _getClassNameFromConfig($configPath, $interface = null) { $className = (string) $this->getConfig()->getNode($configPath); $reflection = Mage_Utils_Reflection::getRelflection($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', $configPath, $interface)); } return $className; }
/** * Reverts environment to previous state * * @return Mage_Test_Model_Fixture */ public function discard() { $fixture = $this->getStorageData(self::STORAGE_KEY_FIXTURE); if (!is_array($fixture)) { $fixture = array(); } $this->_fixture = $fixture; $this->setStorageData(self::STORAGE_KEY_FIXTURE, null); $reflection = Mage_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(); }