diff cake/tests/cases/libs/code_coverage_manager.test.php @ 0:261e66bd5a0c

hg init
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Sun, 24 Jul 2011 21:08:31 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cake/tests/cases/libs/code_coverage_manager.test.php	Sun Jul 24 21:08:31 2011 +0900
@@ -0,0 +1,516 @@
+<?php
+/**
+ * CodeCoverageManagerTest file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ *  Licensed under The Open Group Test Suite License
+ *  Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package       cake
+ * @subpackage    cake.tests.cases.libs
+ * @since         CakePHP(tm) v 1.2.0.4206
+ * @license       http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php';
+require_once CAKE . 'tests' . DS . 'lib' . DS . 'reporter' . DS . 'cake_cli_reporter.php';
+
+/**
+ * CodeCoverageManagerTest class
+ *
+ * @package       cake
+ * @subpackage    cake.tests.cases.libs
+ */
+class CodeCoverageManagerTest extends CakeTestCase {
+
+/**
+ * Skip if XDebug not installed
+ *
+ * @access public
+ */
+	function skip() {
+		$this->skipIf(!extension_loaded('xdebug'), '%s XDebug not installed');
+	}
+
+/**
+ * startTest Method
+ * Store reference of $_GET to restore later.
+ *
+ * @return void
+ */
+	function startCase() {
+		$this->_get = $_GET;
+	}
+
+/**
+ * End Case - restore GET vars.
+ *
+ * @return void
+ */
+	function endCase() {
+		$_GET = $this->_get;
+	}
+
+/**
+ * testNoTestCaseSupplied method
+ *
+ * @access public
+ * @return void
+ */
+	function testNoTestCaseSupplied() {
+		if ($this->skipIf(PHP_SAPI == 'cli', 'Is cli, cannot run this test %s')) {
+			return;
+		}
+		$reporter =& new CakeHtmlReporter(null, array('group' => false, 'app' => false, 'plugin' => false));
+
+		CodeCoverageManager::init(substr(md5(microtime()), 0, 5), $reporter);
+		CodeCoverageManager::report(false);
+		$this->assertError();
+
+		CodeCoverageManager::init('tests' . DS . 'lib' . DS . basename(__FILE__), $reporter);
+		CodeCoverageManager::report(false);
+		$this->assertError();
+	}
+
+/**
+ * Test that test cases don't cause errors
+ *
+ * @return void
+ */
+	function testNoTestCaseSuppliedNoErrors() {
+		if ($this->skipIf(PHP_SAPI == 'cli', 'Is cli, cannot run this test %s')) {
+			return;
+		}
+		$reporter =& new CakeHtmlReporter(null, array('group' => false, 'app' => false, 'plugin' => false));
+		$path = LIBS;
+		if (strpos(LIBS, ROOT) === false) {
+			$path = ROOT.DS.LIBS;
+		}
+		App::import('Core', 'Folder');
+		$folder = new Folder();
+		$folder->cd($path);
+		$contents = $folder->read();
+
+		$contents[1] = array_filter($contents[1], array(&$this, '_basenameFilter'));
+
+		foreach ($contents[1] as $file) {
+			CodeCoverageManager::init('libs' . DS . $file, $reporter);
+			CodeCoverageManager::report(false);
+			$this->assertNoErrors('libs' . DS . $file);
+		}
+	}
+
+/**
+ * Remove file names that don't share a basename with the current file.
+ *
+ * @return void
+ */
+	function _basenameFilter($var) {
+		return ($var != basename(__FILE__));
+	}
+
+/**
+ * testGetTestObjectFileNameFromTestCaseFile method
+ *
+ * @access public
+ * @return void
+ */
+	function testGetTestObjectFileNameFromTestCaseFile() {
+		$manager =& CodeCoverageManager::getInstance();
+		$manager->reporter = new CakeHtmlReporter();
+
+		$expected = $manager->__testObjectFileFromCaseFile('models/some_file.test.php', true);
+		$this->assertIdentical(APP.'models'.DS.'some_file.php', $expected);
+
+		$expected = $manager->__testObjectFileFromCaseFile('models/datasources/some_file.test.php', true);
+		$this->assertIdentical(APP.'models'.DS.'datasources'.DS.'some_file.php', $expected);
+
+		$expected = $manager->__testObjectFileFromCaseFile('controllers/some_file.test.php', true);
+		$this->assertIdentical(APP.'controllers'.DS.'some_file.php', $expected);
+
+		$expected = $manager->__testObjectFileFromCaseFile('views/some_file.test.php', true);
+		$this->assertIdentical(APP.'views'.DS.'some_file.php', $expected);
+
+		$expected = $manager->__testObjectFileFromCaseFile('behaviors/some_file.test.php', true);
+		$this->assertIdentical(APP.'models'.DS.'behaviors'.DS.'some_file.php', $expected);
+
+		$expected = $manager->__testObjectFileFromCaseFile('components/some_file.test.php', true);
+		$this->assertIdentical(APP.'controllers'.DS.'components'.DS.'some_file.php', $expected);
+
+		$expected = $manager->__testObjectFileFromCaseFile('helpers/some_file.test.php', true);
+		$this->assertIdentical(APP.'views'.DS.'helpers'.DS.'some_file.php', $expected);
+
+		$manager->pluginTest = 'bugs';
+		$expected = $manager->__testObjectFileFromCaseFile('models/some_file.test.php', false);
+		$this->assertIdentical(APP.'plugins'.DS.'bugs'.DS.'models'.DS.'some_file.php', $expected);
+
+		$manager->pluginTest = false;
+		$manager->reporter = new CakeCliReporter;
+		$expected = $manager->__testObjectFileFromCaseFile('libs/set.test.php', false);
+		$this->assertIdentical(ROOT.DS.'cake'.DS.'libs'.DS.'set.php', $expected);
+	}
+
+/**
+ * testOfHtmlDiffReport method
+ *
+ * @access public
+ * @return void
+ */
+	function testOfHtmlDiffReport() {
+		$manager =& CodeCoverageManager::getInstance();
+		$code = <<<PHP
+/**
+ * Set class
+ *
+ * @package       cake
+ * @subpackage    cake.tests.cases.libs
+ */
+		class Set extends Object {
+
+/**
+		 * Value of the Set object.
+		 *
+		 * @var array
+		 * @access public
+		 */
+			var \$value = array();
+
+/**
+		 * Constructor. Defaults to an empty array.
+		 *
+		 * @access public
+		 */
+			function __construct() {
+				if (func_num_args() == 1 && is_array(func_get_arg(0))) {
+					\$this->value = func_get_arg(0);
+				} else {
+					\$this->value = func_get_args();
+				}
+			}
+
+/**
+		 * Returns the contents of the Set object
+		 *
+		 * @return array
+		 * @access public
+		 */
+			function &get() {
+				return \$this->value;
+			}
+
+/**
+		 * This function can be thought of as a hybrid between PHP's array_merge and array_merge_recursive. The difference
+		 * to the two is that if an array key contains another array then the function behaves recursive (unlike array_merge)
+		 * but does not do if for keys containing strings (unlike array_merge_recursive). See the unit test for more information.
+		 *
+		 * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.
+		 *
+		 * @param array \$arr1 Array to be merged
+		 * @param array \$arr2 Array to merge with
+		 * @return array Merged array
+		 * @access public
+		 */
+			function merge(\$arr1, \$arr2 = null) {
+				\$args = func_get_args();
+
+				if (isset(\$this) && is_a(\$this, 'set')) {
+					\$backtrace = debug_backtrace();
+					\$previousCall = strtolower(\$backtrace[1]['class'].'::'.\$backtrace[1]['function']);
+					if (\$previousCall != 'set::merge') {
+						\$r =& \$this->value;
+						array_unshift(\$args, null);
+					}
+				}
+				if (!isset(\$r)) {
+					\$r = (array)current(\$args);
+				}
+
+				while ((\$arg = next(\$args)) !== false) {
+					if (is_a(\$arg, 'set')) {
+						\$arg = \$arg->get();
+					}
+
+					foreach ((array)\$arg as \$key => \$val)	 {
+						if (is_array(\$val) && isset(\$r[\$key]) && is_array(\$r[\$key])) {
+							\$r[\$key] = Set::merge(\$r[\$key], \$val);
+						} elseif (is_int(\$key)) {
+
+						} else {
+							\$r[\$key] = \$val;
+						}
+					}
+				}
+				return \$r;
+			}
+PHP;
+
+		$testObjectFile = explode("\n", $code);
+		$coverageData = array(
+			0 => 1,
+			1 => 1,
+			2 => -2,
+			3 => -2,
+			4 => -2,
+			5 => -2,
+			6 => -2,
+			7 => -2,
+			8 => -1,
+			9 => -2,
+			10 => -2,
+			11 => -2,
+			12 => -2,
+			13 => -2,
+			14 => 1,
+			15 => 1,
+			16 => -1,
+			17 => 1,
+			18 => 1,
+			19 => -1,
+			20 => 1,
+			21 => -2,
+			22 => -2,
+			23 => -2,
+			24 => -2,
+			25 => -2,
+			26 => -2,
+			27 => 1,
+			28 => -1,
+			29 => 1,
+			30 => 1,
+			31 => -2,
+			32 => -2,
+			33 => -2,
+			34 => -2,
+			35 => -2,
+			36 => -2,
+			37 => -2,
+			38 => -2,
+			39 => -2,
+			40 => -2,
+			41 => -2,
+			42 => -2,
+			43 => -1,
+			44 => -2,
+			45 => -2,
+			46 => -2,
+			47 => -2,
+			48 => 1,
+			49 => 1,
+			50 => -1,
+			51 => 1,
+			52 => 1,
+			53 => -2,
+			54 => -2,
+			55 => 1,
+			56 => 1,
+			57 => 1,
+			58 => 1,
+			59 => -1,
+			60 => 1,
+			61 => 1,
+			62 => -2,
+			63 => -2,
+			64 => 1,
+			65 => -2,
+			66 => 1,
+			67 => -1,
+			68 => -2,
+			69 => -1,
+			70 => -1,
+			71 => 1,
+			72 => -2,
+		);
+		$expected = array(
+			0 => 'ignored',
+			1 => 'ignored',
+			2 => 'ignored',
+			3 => 'ignored',
+			4 => 'ignored',
+			5 => 'ignored show start realstart',
+			6 => 'ignored show',
+			7 => 'ignored show',
+			8 => 'uncovered show',
+			9 => 'ignored show',
+			10 => 'ignored show',
+			11 => 'ignored show end',
+			12 => 'ignored',
+			13 => 'ignored show start',
+			14 => 'covered show',
+			15 => 'covered show',
+			16 => 'uncovered show',
+			17 => 'covered show show',
+			18 => 'covered show show',
+			19 => 'uncovered show',
+			20 => 'covered show',
+			21 => 'ignored show',
+			22 => 'ignored show end',
+			23 => 'ignored',
+			24 => 'ignored',
+			25 => 'ignored show start',
+			26 => 'ignored show',
+			27 => 'covered show',
+			28 => 'uncovered show',
+			29 => 'covered show',
+			30 => 'covered show',
+			31 => 'ignored show end',
+			32 => 'ignored',
+			33 => 'ignored',
+			34 => 'ignored',
+			35 => 'ignored',
+			36 => 'ignored',
+			37 => 'ignored',
+			38 => 'ignored',
+			39 => 'ignored',
+			40 => 'ignored show start',
+			41 => 'ignored show',
+			42 => 'ignored show',
+			43 => 'uncovered show',
+			41 => 'ignored show',
+			42 => 'ignored show',
+			43 => 'uncovered show',
+			44 => 'ignored show',
+			45 => 'ignored show',
+			46 => 'ignored show',
+			47 => 'ignored show',
+			48 => 'covered show',
+			49 => 'covered show',
+			50 => 'uncovered show',
+			51 => 'covered show',
+			52 => 'covered show',
+			53 => 'ignored show end',
+			54 => 'ignored',
+			55 => 'covered',
+			56 => 'covered show start',
+			57 => 'covered show',
+			58 => 'covered show',
+			59 => 'uncovered show',
+			60 => 'covered show',
+			61 => 'covered show',
+			62 => 'ignored show end',
+			63 => 'ignored',
+			64 => 'covered show start',
+			65 => 'ignored show',
+			66 => 'covered show show',
+			67 => 'uncovered show',
+			68 => 'ignored show',
+			69 => 'uncovered show',
+			70 => 'uncovered show',
+			71 => 'covered show',
+			72 => 'ignored show',
+			73 => 'ignored show end end',
+		);
+		$execCodeLines = range(0, 72);
+		$result = explode("</div>", $report = $manager->reportCaseHtmlDiff($testObjectFile, $coverageData, $execCodeLines, 3));
+
+		foreach ($result as $line) {
+			preg_match('/<span class="line-num">(.*?)<\/span>/', $line, $matches);
+			if (!isset($matches[1])) {
+				continue;
+			}
+
+			$num = $matches[1];
+			$class = $expected[$num];
+			$pattern = '/<div class="code-line '.$class.'">/';
+			$this->assertPattern($pattern, $line, $num.': '.$line." fails");
+		}
+	}
+
+/**
+ * testArrayStrrpos method
+ *
+ * @access public
+ * @return void
+ */
+	function testArrayStrrpos() {
+		$manager =& CodeCoverageManager::getInstance();
+
+		$a = array(
+			'apples',
+			'bananas',
+			'oranges'
+		);
+		$this->assertEqual(1, $manager->__array_strpos($a, 'ba', true));
+		$this->assertEqual(2, $manager->__array_strpos($a, 'range', true));
+		$this->assertEqual(0, $manager->__array_strpos($a, 'pp', true));
+		$this->assertFalse($manager->__array_strpos('', 'ba', true));
+		$this->assertFalse($manager->__array_strpos(false, 'ba', true));
+		$this->assertFalse($manager->__array_strpos(array(), 'ba', true));
+
+		$a = array(
+			'rang',
+			'orange',
+			'oranges'
+		);
+		$this->assertEqual(0, $manager->__array_strpos($a, 'rang'));
+		$this->assertEqual(2, $manager->__array_strpos($a, 'rang', true));
+		$this->assertEqual(1, $manager->__array_strpos($a, 'orange', false));
+		$this->assertEqual(1, $manager->__array_strpos($a, 'orange'));
+		$this->assertEqual(2, $manager->__array_strpos($a, 'orange', true));
+	}
+
+/**
+ * testGetExecutableLines method
+ *
+ * @access public
+ * @return void
+ */
+	function testGetExecutableLines() {
+		$manager =& CodeCoverageManager::getInstance();
+		$code = <<<HTML
+			\$manager =& CodeCoverageManager::getInstance();
+HTML;
+		$result = $manager->__getExecutableLines($code);
+		foreach ($result as $line) {
+			$this->assertNotIdentical($line, '');
+		}
+
+		$code = <<<HTML
+		{
+		}
+		<?php?>
+		?>
+		<?
+}
+{{}}
+(())
+		@codeCoverageIgnoreStart
+		some
+		more
+		code
+		here
+		@codeCoverageIgnoreEnd
+HTML;
+		$result = $manager->__getExecutableLines($code);
+		foreach ($result as $line) {
+			$this->assertIdentical(trim($line), '');
+		}
+	}
+
+/**
+ * testCalculateCodeCoverage method
+ *
+ * @access public
+ * @return void
+ */
+	function testCalculateCodeCoverage() {
+		$manager =& CodeCoverageManager::getInstance();
+		$data = array(
+			'25' => array(100, 25),
+			'50' => array(100, 50),
+			'0' => array(0, 0),
+			'0' => array(100, 0),
+			'100' => array(100, 100),
+		);
+		foreach ($data as $coverage => $lines) {
+			$this->assertEqual($coverage, $manager->__calcCoverage($lines[0], $lines[1]));
+		}
+
+		$manager->__calcCoverage(100, 1000);
+		$this->assertError();
+	}
+}