Finds the classes or namespaces belonging to a particular library. _Note_: This method
assumes loaded class libraries use a consistent class-to-file naming convention.
public static find ( mixed $library, array $options = [] ) : array | ||
$library | mixed | The name of a library added to the application with `Libraries::add()`, or `true` to search all libraries. |
$options | array | The options this method accepts: - `'path'` _string_: A physical filesystem path relative to the directory of the library being searched. If provided, only the classes or namespaces within this path will be returned. - `'recursive'` _boolean_: If `true`, recursively searches all directories (namespaces) in the given library. If `false` (the default), only searches the top level of the given path. - `'filter'` _string_: A regular expression applied to a class after it is transformed into a fully-namespaced class name. The default regular expression filters class names based on the [PSR-0](http://groups.google.com/group/php-standards/web/psr-0-final-proposal) PHP 5.3 naming standard. - `'exclude'` _mixed_: Can be either a regular expression of classes/namespaces to exclude, or a PHP callable to be used with `array_filter()`. - `'namespaces'` _boolean_: Indicates whether namespaces should be included in the search results. If `false` (the default), only classes are returned. |
return | array | Returns an array of fully-namespaced class names found in the given library or libraries. |
/** * Main method. * * @param string $path Absolute path to file or directory. * @return boolean */ public function run() { $path = $this->request->action; if (!($path = realpath($path))) { $this->error('Not a valid path.'); return false; } if (!($library = $this->_library($path))) { $this->error("No library registered for path `{$path}`."); return false; } $classes = Libraries::find($library, array('recursive' => true, 'exclude' => '/tests|resources|webroot|index$|^app\\\\config|^app\\\\views|Exception$/')); $tests = array(); foreach (Group::all() as $test) { $class = preg_replace('/(tests\\\\[a-z]+\\\\|Test$)/', null, $test); $tests[$class] = $test; } foreach ($classes as $class) { $coverage = null; if ($hasTest = isset($tests[$class])) { $report = Dispatcher::run($tests[$class], array('reporter' => 'console', 'format' => 'txt', 'filters' => array('Coverage'))); $coverage = $report->results['filters']['lithium\\test\\filter\\Coverage']; $coverage = isset($coverage[$class]) ? $coverage[$class]['percentage'] : null; } $this->out(sprintf('%10s | %7s | %s', $hasTest ? 'has test' : 'no test', is_numeric($coverage) ? sprintf('%.2f%%', $coverage) : 'n/a', $class)); } }
/** * Add a tests to the group * * @param string $test * @param string $options * @return array */ public function add($test = null, $options = array()) { $callback = function ($test) { if (empty($test)) { return array(); } if (is_object($test) && $test instanceof \lithium\test\Unit) { return array(get_class($test)); } if (is_string($test)) { if ($test[0] != '\\') { $test = "lithium\\tests\\cases\\{$test}"; } if (preg_match("/Test/", $test)) { return array($test); } $parts = array_filter(explode("\\", $test)); $library = array_shift($parts); $test = Libraries::find($library, array('recursive' => true, 'path' => '/' . join('/', $parts), 'filter' => '/cases|intergration|functional/')); return (array) $test; } return (array) $test; }; if (is_array($test)) { foreach ($test as $t) { $this->_items = array_filter(array_merge($this->_items, $callback($t))); } return $this->_items; } return $this->_items = array_merge($this->_items, $callback($test)); }
public function run($library = 'lithium') { $libs = Libraries::find($library, array('recursive' => true)); $files = array(); foreach ((array) $libs as $lib) { $file = Libraries::path($lib); $this->_display($file); } }
public function run() { $classes = Libraries::find(true, array('exclude' => "/webroot|index\$|^app\\\\config|^app\\\\views/", 'recursive' => true)); foreach ($classes as $class) { $path = Libraries::path($class); $contents = explode("\n", file_get_contents($path)); $contents = $this->_header($contents); if (file_put_contents($path, implode("\n", $contents))) { $this->out($path . ' written'); } } }
public static function harvest() { $extractor = $this->_classes['extractor']; $results = array(); foreach (Libraries::get() as $library => $info) { $libFiles = Libraries::find($library, array('recursive' => true, 'exclude' => '/mocks|tests|libraries/')); foreach ($libFiles as $file) { $this->out("\n" . $file); $fileData = $extractor::get($library, $file); $results = array_merge(static::_harvestMethods($fileData), static::_harvestProperties($fileData), array(static::_harvestClass($fileData))); } } return new Collection(array('data' => $results)); }
/** * Extracts data from files within configured path recursively. * * @param string $category Dot-delimited category. * @param string $locale A locale identifier. * @param string $scope The scope for the current operation. * @return mixed */ public function read($category, $locale, $scope) { if ($scope != $this->_config['scope']) { return null; } $library = Libraries::get($this->_config['library']); $data = array(); $classes = Libraries::find($this->_config['library'], array('recursive' => true, 'exclude' => '/\\w+Test$|Mock+\\w|webroot|index$|^app\\\\config|^\\w+\\\\views\\/|\\./')); foreach ($classes as $class) { if (preg_match('/\\\\(libraries|plugins)\\\\/', $class)) { continue; } $data += $this->_parseClass($class); } return $data; }
/** * Main command logic. * * @return void */ public function run() { $this->_readyTables(); $extractor = $this->_classes['extractor']; $libraries = Libraries::get(); foreach ($libraries as $library => $info) { $this->header($library); $libFiles = Libraries::find($library, array('recursive' => true, 'exclude' => '/mocks|tests|libraries/')); foreach ($libFiles as $file) { $this->out("\n" . $file); $fileData = $extractor::get($library, $file); $this->_harvestMethods($fileData); $this->_harvestProperties($fileData); $this->_harvestClass($fileData); } $this->out("\n\n"); } $this->out("\n\n"); }
/** * Returns all classes directly depending on a given class. * * @param string $dependency The class name to use as a dependency. * @param string $exclude Regex path exclusion filter. * @return array Classes having a direct dependency on `$dependency`. May contain duplicates. */ protected static function _affected($dependency, $exclude = null) { $exclude = $exclude ?: '/(tests|webroot|resources|libraries|plugins)/'; $classes = Libraries::find(true, compact('exclude') + array('recursive' => true)); $dependency = ltrim($dependency, '\\'); $affected = array(); foreach ($classes as $class) { if (isset(static::$_cachedDepends[$class])) { $depends = static::$_cachedDepends[$class]; } else { $depends = Inspector::dependencies($class); $depends = array_map(function ($c) { return ltrim($c, '\\'); }, $depends); static::$_cachedDepends[$class] = $depends; } if (in_array($dependency, $depends)) { $affected[] = $class; } } return $affected; }
protected static function _children($library, $path) { $result = array(); $types = array('namespace' => array('namespaces' => true), 'class' => array('namespaces' => false), 'file' => array('namespaces' => false, 'filter' => false, 'preFilter' => false)); foreach ($types as $type => $options) { foreach (Libraries::find($library, compact('path') + $options) as $child) { $result += array($child => $type); } } return $result; }
/** * Shows which classes are un-tested. * * @return void */ public function missing() { $this->header('Classes with no test case'); $classes = Libraries::find(true, array('recursive' => true, 'exclude' => '/\\w+Test$|webroot|index$|^app\\\\config|^app\\\\views/')); $tests = Group::all(); $classes = array_diff($classes, $tests); sort($classes); $this->out($classes); }
public function testLocateWithLithiumLibrary() { $expected = (array) Libraries::find('lithium', array('path' => '/tests', 'preFilter' => '/[A-Z][A-Za-z0-9]+\\Test\\./', 'recursive' => true, 'filter' => '/cases|integration|functional|mocks/')); $result = (array) Libraries::locate("tests", null, array('library' => 'lithium')); $this->assertEqual($expected, $result); }
public function testAddTestAppGroup() { $testApp = Libraries::get(true, 'resources') . '/tmp/tests/test_app'; mkdir($testApp, 0777, true); Libraries::add('test_app', array('path' => $testApp)); mkdir($testApp . '/tests/cases/models', 0777, true); file_put_contents($testApp . '/tests/cases/models/UserTest.php', "<?php namespace test_app\\tests\\cases\\models;\n\n\t\t\tclass UserTest extends \\lithium\\test\\Unit { public function testMe() {\n\t\t\t\t\$this->assertTrue(true);\n\t\t\t}}"); Libraries::cache(false); $expected = (array) Libraries::find('test_app', array('recursive' => true, 'path' => '/tests', 'filter' => '/cases|integration|functional/')); Libraries::cache(false); $group = new Group(); $result = $group->add('test_app'); $this->assertEqual($expected, $result); Libraries::cache(false); $this->_cleanUp(); }
/** * Resolves a unit test class (or classes) from a class or namespace path string. * * @param string $test The path string in which to find the test case(s). This may be a * library, a namespace, or a fully-namespaced class reference. * @return array Returns an array containing one or more fully-namespaced class references to * unit tests. */ protected function _resolve($test) { if (strpos($test, '\\') === false && Libraries::get($test)) { return (array) Libraries::find($test, array('recursive' => true, 'filter' => '/(cases|integration|functional)\\\\.*Test$/', 'exclude' => '/tests\\\\mocks/')); } if (!($test = trim($test, '\\'))) { return array(); } list($library, $path) = explode('\\', $test, 2) + array($test, null); return (array) Libraries::find($library, array('recursive' => true, 'path' => '/' . str_replace('\\', '/', $path), 'filter' => '/(cases|integration|functional)\\\\.*Test$/', 'exclude' => strstr($test, 'tests\\mocks') ? '' : '/tests\\\\mocks/')); }
public function testFindWithOptions() { $result = Libraries::find('lithium', array('path' => '/console/command/create/template', 'namespaces' => false, 'suffix' => false, 'filter' => false, 'exclude' => false, 'format' => function ($file, $config) { return basename($file); })); $this->assertTrue(count($result) > 3); $this->assertTrue(array_search('controller.txt.php', $result)); $this->assertTrue(array_search('model.txt.php', $result)); $this->assertTrue(array_search('plugin.phar.gz', $result)); }
/** * Resolves a unit test class (or classes) from a class or namespace path string. * * @param string $test The path string in which to find the test case(s). This may be a * library, a namespace, or a fully-namespaced class reference. * @return array Returns an array containing one or more fully-namespaced class references to * unit tests. */ protected function _resolve($test) { if (strpos($test, '\\') === false && Libraries::get($test)) { return (array) Libraries::find($test, array('recursive' => true, 'filter' => '/cases|integration|functional/')); } if (preg_match("/Test/", $test)) { return array($test); } if (!($test = trim($test, '\\'))) { return array(); } list($library, $path) = explode('\\', $test, 2) + array($test, null); return (array) Libraries::find($library, array('recursive' => true, 'path' => '/' . str_replace('\\', '/', $path), 'filter' => '/cases|integration|functional/')); }
/** * Gets a unit test class (or classes) from a class or namespace path string. * * @param string $test The path string in which to find the test case(s). This may be a * namespace, a Lithium package name, or a fully-namespaced class reference. * @return array Returns an array containing one or more fully-namespaced class references to * unit tests. */ protected function _unitClass($test) { if ($test[0] != '\\' && strpos($test, 'lithium\\') === false) { if (file_exists(Libraries::path($test = "lithium\\tests\\cases\\{$test}"))) { return array($test); } } if (preg_match("/Test/", $test)) { return array($test); } if (!($test = trim($test, '\\'))) { return array(); } list($library, $path) = explode('\\', $test, 2) + array($test, null); return (array) Libraries::find($library, array('recursive' => true, 'path' => '/' . str_replace('\\', '/', $path), 'filter' => '/cases|integration|functional/')); }