Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jun 02, 2012
@raisinbread Style guide compliance. fd9fc96
Commits on Jun 12, 2012
@raisinbread Adding beginning tests. 349f819
View
86 extensions/command/Documented.php
@@ -9,8 +9,6 @@
namespace li3_qa\extensions\command;
-use lithium\core\Libraries;
-
/**
* Checks files for documentation coverage (via doc blocks).
*/
@@ -42,7 +40,7 @@ class Documented extends \lithium\console\Command {
*
* @var string
**/
- protected $ignore = '/template|tests/i';
+ protected $ignore = '/template|tests|views/i';
/**
* Main method.
@@ -50,12 +48,13 @@ class Documented extends \lithium\console\Command {
* @param string $path Absolute path to file or directory.
* @return boolean
*/
- public function run() {
- if($files = $this->_getFiles($this->request->action)) {
- foreach($files as $file) {
- $this->_checkFile($file[0]);
+ public function run($path = '.') {
+ if ($files = $this->_getFiles($path)) {
+ foreach ($files as $file) {
+ $this->checkFile($file[0]);
}
}
+ $this->out("\n{:green}Check complete.{:end}");
return true;
}
@@ -65,9 +64,9 @@ public function run() {
* @param string $path Path to file to be inspected.
* @return void
**/
- protected function _checkFile($path) {
- if(preg_match($this->ignore, $path) == 1){
- return;
+ public function checkFile($path) {
+ if (preg_match($this->ignore, $path) == 1){
+ return true;
}
$this->errors = array();
@@ -77,20 +76,20 @@ protected function _checkFile($path) {
$this->_checkClassDocBlock();
$this->_checkDocBlocks();
- if(count($this->errors)) {
- $this->out();
- $this->out($this->path);
- $this->out(implode("\n", $this->errors));
+ if (count($this->errors)) {
+ $this->out("\n" . $this->path . "\n" . implode("\n", $this->errors));
+ return false;
}
+ return true;
}
protected function debug($tokens = null) {
- if($tokens == null) {
+ if ($tokens == null) {
$tokens = $this->tokens;
}
- foreach($tokens as &$token) {
- if(is_array($token)) {
+ foreach ($tokens as &$token) {
+ if (is_array($token)) {
$token[0] = token_name($token[0]);
}
}
@@ -98,38 +97,36 @@ protected function debug($tokens = null) {
}
/**
- * Ensures each class variable is documented. The assumption is that if a
- * variable is preceeded by a scope definition, it's a class variable.
+ * Ensures each class variable or method is documented. The assumption is that if a
+ * member is preceeded by a scope definition, it needs docs.
*
* @return void
**/
protected function _checkDocBlocks() {
- for($i = 0; $i < count($this->tokens); $i++) {
- if($this->tokens[$i][0] == T_VARIABLE || $this->tokens[$i][0] == T_FUNCTION) {
+ for ($i = 0; $i < count($this->tokens); $i++) {
+ if ($this->tokens[$i][0] == T_VARIABLE || $this->tokens[$i][0] == T_FUNCTION) {
// Get the previous tokens.
// Max is 8, allows for abstract, scope, static markers.
$leadingTokens = array();
$leadingTokenTypes = array();
- for($j = 1; $j < 9; $j++) {
- if(!isset($this->tokens[$i - $j])) {
+ for ($j = 1; $j < 9; $j++) {
+ if (!isset($this->tokens[$i - $j])) {
break;
}
$leadingTokens[$i - $j] = $this->tokens[$i - $j];
$leadingTokenTypes[$i - $j] = $this->tokens[$i - $j][0];
// Don't parse farther past if you run into another var/function.
- if($this->tokens[$i - $j][0] == T_VARIABLE || $this->tokens[$i - $j][0] == T_FUNCTION) {
+ if (in_array($this->tokens[$i - $j][0], array(T_VARIABLE, T_FUNCTION))) {
break;
}
}
// Check for a scope operator. Lack of one means we've hit a
// closure or a non-class var that can be ignored.
// Hit means this needs documentation.
- if(
- (in_array(T_PUBLIC, $leadingTokenTypes) ||
- in_array(T_PROTECTED, $leadingTokenTypes) ||
- in_array(T_PRIVATE, $leadingTokenTypes)) &&
- !in_array(T_DOC_COMMENT, $leadingTokenTypes)
- ) {
+ $scoped = in_array(T_PUBLIC, $leadingTokenTypes) ||
+ in_array(T_PROTECTED, $leadingTokenTypes) ||
+ in_array(T_PRIVATE, $leadingTokenTypes);
+ if ($scoped && !in_array(T_DOC_COMMENT, $leadingTokenTypes)) {
$this->_error($i);
}
}
@@ -142,13 +139,13 @@ protected function _checkDocBlocks() {
* @return void
**/
protected function _checkClassDocBlock() {
- for($i = 0; $i < count($this->tokens); $i++) {
- if($this->tokens[$i][0] == T_CLASS) {
+ for ($i = 0; $i < count($this->tokens); $i++) {
+ if ($this->tokens[$i][0] == T_CLASS) {
$abMod = 0;
- if($this->tokens[$i - 2][0] == T_ABSTRACT) {
+ if ($this->tokens[$i - 2][0] == T_ABSTRACT) {
$abMod = 2;
}
- if($this->tokens[$i - (2 + $abMod)][0] != T_DOC_COMMENT) {
+ if ($this->tokens[$i - (2 + $abMod)][0] != T_DOC_COMMENT) {
$line = str_pad("line {$this->tokens[$i][2]}:", 10);
$this->_error($i);
}
@@ -162,12 +159,11 @@ protected function _checkClassDocBlock() {
* @return void
**/
protected function _checkHeader() {
- if(!isset($this->tokens[1][0]) ||
- !isset($this->tokens[1][1]) ||
- $this->tokens[1][0] != T_DOC_COMMENT ||
- strstr($this->tokens[1][1], 'Lithium: the most rad php framework') === false
- ) {
- $line = str_pad("line {$this->tokens[1][2]}:", 10);
+ if (!isset($this->tokens[1]) || !is_array($this->tokens[1])) {
+ $this->_error(1);
+ }
+ $containsHeader = strstr($this->tokens[1][1], 'the most rad php framework') === false;
+ if ($this->tokens[1][0] != T_DOC_COMMENT || $containsHeader) {
$this->_error(1);
}
}
@@ -175,11 +171,11 @@ protected function _checkHeader() {
/**
* Outputs an error to the console based on the current file being processed.
*
- * @param string $message Message to output.
+ * @param integer $tokenIndex Token related to error.
* @return void
**/
protected function _error($tokenIndex) {
- if($tokenIndex == 1) {
+ if ($tokenIndex == 1) {
$error = "line: 1\tNo file header found.";
$this->errors[] = "\t{:red}$error{:end}";
return;
@@ -214,10 +210,12 @@ protected function _getFiles($path) {
$this->error('Not a valid path.');
return false;
}
- if(is_file($path)) {
+ if (is_file($path)) {
return array(array($path));
}
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
return new \RegexIterator($iterator, '/^.+\.php$/i', \RecursiveRegexIterator::GET_MATCH);
}
-}
+}
+
+?>
View
113 tests/cases/console/command/DocumentedTest.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace li3_qa\tests\cases\console\command;
+
+use lithium\console\Request;
+use lithium\core\Libraries;
+use li3_qa\extensions\command\Documented;
+
+class DocumentedTest extends \lithium\test\Unit {
+
+ protected $_files = array();
+
+ public function setUp() {
+ $this->classes = array('response' => 'lithium\tests\mocks\console\MockResponse');
+ $this->request = new Request(array('input' => fopen('php://temp', 'w+')));
+ }
+
+ public function tearDown() {
+ foreach ($this->_files as $file) {
+ if(file_exists($file)) {
+ unlink($file);
+ }
+ }
+ }
+
+ public function testRun() {
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ $this->assertTrue($command->run(''));
+ }
+
+ public function testPath() {
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ $command->run('/foo/bar');
+ $expected = preg_quote('Not a valid path');
+ $this->assertPattern("/{$expected}/", $command->response->error);
+
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ $command->run(__FILE__);
+ $expected = preg_quote('Check complete');
+ $this->assertPattern("/{$expected}/", $command->response->output);
+ }
+
+ public function testHeader() {
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ $noHeader = $this->_tempFileWithContents("<?php echo 'foo'; ?>");
+ $result = $command->checkFile($noHeader);
+ $expected = preg_quote('No file header found');
+ $this->assertPattern("/{$expected}/", $command->response->output);
+ $this->assertTrue(!$result);
+
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ $contents = "<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace foo\bar;
+
+/**
+ * Class docs.
+ *
+ */
+class Foo {}
+?>";
+ $noHeader = $this->_tempFileWithContents($contents);
+ $this->assertTrue($command->checkFile($noHeader));
+ }
+
+ protected function _tempFileWithContents($contents) {
+ $path = Libraries::get(true, 'resources') . '/tmp/' . uniqid() . '.php';
+ $this->_files[] = $path;
+ file_put_contents($path, $contents);
+ return $path;
+ }
+
+ public function testClassDocBlock() {
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ $contents = "<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace foo\bar;
+
+class Foo {}
+?>";
+ $noClassDocs = $this->_tempFileWithContents($contents);
+ $this->assertTrue(!$command->checkFile($noClassDocs));
+
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ $command->run($noClassDocs);
+ $expected = preg_quote('Class Foo not documented');
+ $this->assertPattern("/{$expected}/", $command->response->output);
+ }
+
+ public function testClassVarsDocBlocks() {
+ $command = new Documented(array('request' => $this->request, 'classes' => $this->classes));
+ }
+}
+
+?>

No commit comments for this range

Something went wrong with that request. Please try again.