/** * Set upt the test environment */ public function setUp() { $this->dataDirs = array(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Data'); // get the objects we need $config = new Config(); $config->setValue('autoload/dirs', $this->dataDirs); $config->setValue('enforcement/dirs', array()); $this->structureMap = new StructureMap($config->getValue('autoload/dirs'), $config->getValue('enforcement/dirs'), $config); // fill the map $this->structureMap->fill(); }
/** * Will return true if the specified file has specified contracts, false if not. * * @param string $file File to check for contracts * * @return bool */ protected function findContracts($file) { // We need to get our array of needles $needles = array(PBC_KEYWORD_INVARIANT, PBC_KEYWORD_POST, PBC_KEYWORD_PRE); // If we have to enforce things like @param or @returns, we have to be more sensitive if ($this->config->getValue('enforcement/enforce-default-type-safety') === true) { $needles[] = '@var'; $needles[] = '@param'; $needles[] = '@return'; } // Open the file and search it piece by piece until we find something or the file ends. $rsc = fopen($file, 'r'); $recent = ''; while (!feof($rsc)) { // Get a current chunk $current = fread($rsc, 512); // We also check the last chunk as well, to avoid cutting the only needle we have in two. $haystack = $recent . $current; foreach ($needles as $needle) { // If we found something we can return true if (strpos($haystack, $needle) !== false) { return true; } } // Set recent for the next iteration $recent = $current; } // Still here? So nothing was found. return false; }
/** * Will load any given structure based on it's availability in our structure map which depends on the configured * project directories. * If the structure cannot be found we will redirect to the composer autoloader which we registered as a fallback * * @param string $className The name of the structure we will try to load * * @return bool */ public function loadClass($className) { // There was no file in our cache dir, so lets hope we know the original path of the file. $autoLoaderConfig = $this->config->getConfig('autoloader'); // Might the class be a omitted one? If so we can require the original. if (isset($autoLoaderConfig['omit'])) { foreach ($autoLoaderConfig['omit'] as $omitted) { // If our class name begins with the omitted part e.g. it's namespace if (strpos($className, str_replace('\\\\', '\\', $omitted)) === 0) { return false; } } } // Do we have the file in our cache dir? If we are in development mode we have to ignore this. $cacheConfig = $this->config->getConfig('cache'); if ($this->config->getConfig('environment') !== 'development') { $cachePath = $cacheConfig['dir'] . DIRECTORY_SEPARATOR . str_replace('\\', '_', $className) . '.php'; if (is_readable($cachePath)) { $res = fopen($cachePath, 'r'); $str = fread($res, 384); $success = preg_match('/' . PBC_ORIGINAL_PATH_HINT . '(.+)' . PBC_ORIGINAL_PATH_HINT . '/', $str, $tmp); if ($success > 0) { $tmp = explode('#', $tmp[1]); $path = $tmp[0]; $mTime = $tmp[1]; if (filemtime($path) == $mTime) { require $cachePath; return true; } } } } // If we are loading something of our own library we can skip to composer if (strpos($className, 'TechDivision\\PBC') === 0 && strpos($className, 'TechDivision\\PBC\\Tests') === false || strpos($className, 'PHP') === 0) { return false; } // If the structure map did not get filled by now we will do so here if ($this->structureMap->isEmpty()) { $this->structureMap->fill(); } // Get the file from the map $file = $this->structureMap->getEntry($className); // Did we get something? If not return false. if ($file === false) { return false; } // We are still here, so we know the class and it is not omitted. Does it contain contracts then? if (!$file->hasContracts() || !$file->isEnforced()) { require $file->getPath(); return true; } // So we have to create a new class definition for this original class. // Get a current cache instance if we do not have one already. if ($this->cache === null) { // We also require the classes of our maps as we do not have proper autoloading in place $this->cache = new CacheMap($cacheConfig['dir'], array(), $this->config); } $this->generator = new Generator($this->structureMap, $this->cache, $this->config); // Create the new class definition if ($this->generator->create($file, $this->config->getValue('enforcement/contract-inheritance')) === true) { // Require the new class, it should have been created now $file = $this->generator->getFileName($className); if (is_readable($file) === true) { require $file; return true; } } else { return false; } // Still here? That sounds like bad news! return false; }
/** * Test the extendValue() method * * @return void * * @depends testSetValue * @depends testGetValue */ public function testExtendValue() { // Get our config $config = new Config(); // Test string concatination $config->extendValue('environment', 'test'); $this->assertEquals('productiontest', $config->getValue('environment')); // Test array extension $config->extendValue('enforcement/omit', array('Tests')); $this->assertEquals(array('PHPUnit', 'Psr\\Log', 'PHP', 'Tests'), $config->getValue('enforcement/omit')); }