PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/phpunit/3.4.0/PHPUnit/Util/Skeleton/Test.php

https://github.com/vivid-planet/library
PHP | 386 lines | 259 code | 53 blank | 74 comment | 45 complexity | d46aab33232f26d7f6fc3a8ca47497ae MD5 | raw file
  1. <?php
  2. /**
  3. * PHPUnit
  4. *
  5. * Copyright (c) 2002-2009, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * * Neither the name of Sebastian Bergmann nor the names of his
  21. * contributors may be used to endorse or promote products derived
  22. * from this software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  27. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  28. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  29. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  30. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  32. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  34. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. * POSSIBILITY OF SUCH DAMAGE.
  36. *
  37. * @category Testing
  38. * @package PHPUnit
  39. * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
  40. * @copyright 2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
  41. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  42. * @version SVN: $Id: Test.php 5162 2009-08-29 08:49:43Z sb $
  43. * @link http://www.phpunit.de/
  44. * @since File available since Release 3.3.0
  45. */
  46. require_once 'PHPUnit/Util/Filesystem.php';
  47. require_once 'PHPUnit/Util/Filter.php';
  48. require_once 'PHPUnit/Util/Skeleton.php';
  49. require_once 'PHPUnit/Util/Template.php';
  50. PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
  51. /**
  52. * Generator for test class skeletons from classes.
  53. *
  54. * @category Testing
  55. * @package PHPUnit
  56. * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
  57. * @copyright 2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
  58. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  59. * @version Release: @package_version@
  60. * @link http://www.phpunit.de/
  61. * @since Class available since Release 3.3.0
  62. */
  63. class PHPUnit_Util_Skeleton_Test extends PHPUnit_Util_Skeleton
  64. {
  65. /**
  66. * @var array
  67. */
  68. protected $methodNameCounter = array();
  69. /**
  70. * Constructor.
  71. *
  72. * @param string $inClassName
  73. * @param string $inSourceFile
  74. * @param string $outClassName
  75. * @param string $outSourceFile
  76. * @throws RuntimeException
  77. */
  78. public function __construct($inClassName, $inSourceFile = '', $outClassName = '', $outSourceFile = '')
  79. {
  80. if (class_exists($inClassName)) {
  81. $reflector = new ReflectionClass($inClassName);
  82. $inSourceFile = $reflector->getFileName();
  83. if ($inSourceFile !== FALSE) {
  84. $inSourceFile = '<internal>';
  85. }
  86. unset($reflector);
  87. } else {
  88. if (empty($inSourceFile)) {
  89. $possibleFilenames = array(
  90. $inClassName . '.php',
  91. PHPUnit_Util_Filesystem::classNameToFilename($inClassName)
  92. );
  93. foreach ($possibleFilenames as $possibleFilename) {
  94. if (is_file($possibleFilename)) {
  95. $inSourceFile = $possibleFilename;
  96. }
  97. }
  98. }
  99. if (empty($inSourceFile)) {
  100. throw new PHPUnit_Framework_Exception(
  101. sprintf(
  102. 'Neither "%s" nor "%s" could be opened.',
  103. $possibleFilenames[0],
  104. $possibleFilenames[1]
  105. )
  106. );
  107. }
  108. if (!is_file($inSourceFile)) {
  109. throw new PHPUnit_Framework_Exception(
  110. sprintf(
  111. '"%s" could not be opened.',
  112. $inSourceFile
  113. )
  114. );
  115. }
  116. $inSourceFile = realpath($inSourceFile);
  117. include_once $inSourceFile;
  118. if (!class_exists($inClassName)) {
  119. throw new PHPUnit_Framework_Exception(
  120. sprintf(
  121. 'Could not find class "%s" in "%s".',
  122. $inClassName,
  123. $inSourceFile
  124. )
  125. );
  126. }
  127. }
  128. if (empty($outClassName)) {
  129. $outClassName = $inClassName . 'Test';
  130. }
  131. if (empty($outSourceFile)) {
  132. $outSourceFile = dirname($inSourceFile) . DIRECTORY_SEPARATOR . $outClassName . '.php';
  133. }
  134. parent::__construct(
  135. $inClassName, $inSourceFile, $outClassName, $outSourceFile
  136. );
  137. }
  138. /**
  139. * Generates the test class' source.
  140. *
  141. * @param boolean $verbose
  142. * @return mixed
  143. */
  144. public function generate($verbose = FALSE)
  145. {
  146. $class = new ReflectionClass(
  147. $this->inClassName['fullyQualifiedClassName']
  148. );
  149. $methods = '';
  150. $incompleteMethods = '';
  151. foreach ($class->getMethods() as $method) {
  152. if (!$method->isConstructor() &&
  153. !$method->isAbstract() &&
  154. $method->isPublic() &&
  155. $method->getDeclaringClass()->getName() == $this->inClassName['fullyQualifiedClassName']) {
  156. $assertAnnotationFound = FALSE;
  157. if (preg_match_all('/@assert(.*)$/Um', $method->getDocComment(), $annotations)) {
  158. foreach ($annotations[1] as $annotation) {
  159. if (preg_match('/\((.*)\)\s+([^\s]*)\s+(.*)/', $annotation, $matches)) {
  160. switch ($matches[2]) {
  161. case '==': {
  162. $assertion = 'Equals';
  163. }
  164. break;
  165. case '!=': {
  166. $assertion = 'NotEquals';
  167. }
  168. break;
  169. case '===': {
  170. $assertion = 'Same';
  171. }
  172. break;
  173. case '!==': {
  174. $assertion = 'NotSame';
  175. }
  176. break;
  177. case '>': {
  178. $assertion = 'GreaterThan';
  179. }
  180. break;
  181. case '>=': {
  182. $assertion = 'GreaterThanOrEqual';
  183. }
  184. break;
  185. case '<': {
  186. $assertion = 'LessThan';
  187. }
  188. break;
  189. case '<=': {
  190. $assertion = 'LessThanOrEqual';
  191. }
  192. break;
  193. case 'throws': {
  194. $assertion = 'exception';
  195. }
  196. break;
  197. default: {
  198. throw new PHPUnit_Framework_Exception(
  199. sprintf(
  200. 'Token "%s" could not be parsed in @assert annotation.',
  201. $matches[2]
  202. )
  203. );
  204. }
  205. }
  206. if ($assertion == 'exception') {
  207. $template = 'TestMethodException';
  208. }
  209. else if ($assertion == 'Equals' &&
  210. strtolower($matches[3]) == 'true') {
  211. $assertion = 'True';
  212. $template = 'TestMethodBool';
  213. }
  214. else if ($assertion == 'NotEquals' &&
  215. strtolower($matches[3]) == 'true') {
  216. $assertion = 'False';
  217. $template = 'TestMethodBool';
  218. }
  219. else if ($assertion == 'Equals' &&
  220. strtolower($matches[3]) == 'false') {
  221. $assertion = 'False';
  222. $template = 'TestMethodBool';
  223. }
  224. else if ($assertion == 'NotEquals' &&
  225. strtolower($matches[3]) == 'false') {
  226. $assertion = 'True';
  227. $template = 'TestMethodBool';
  228. }
  229. else {
  230. $template = 'TestMethod';
  231. }
  232. if ($method->isStatic()) {
  233. $template .= 'Static';
  234. }
  235. $methodTemplate = new PHPUnit_Util_Template(
  236. sprintf(
  237. '%s%sTemplate%s%s.tpl',
  238. dirname(__FILE__),
  239. DIRECTORY_SEPARATOR,
  240. DIRECTORY_SEPARATOR,
  241. $template
  242. )
  243. );
  244. $origMethodName = $method->getName();
  245. $methodName = ucfirst($origMethodName);
  246. if (isset($this->methodNameCounter[$methodName])) {
  247. $this->methodNameCounter[$methodName]++;
  248. } else {
  249. $this->methodNameCounter[$methodName] = 1;
  250. }
  251. if ($this->methodNameCounter[$methodName] > 1) {
  252. $methodName .= $this->methodNameCounter[$methodName];
  253. }
  254. $methodTemplate->setVar(
  255. array(
  256. 'annotation' => trim($annotation),
  257. 'arguments' => $matches[1],
  258. 'assertion' => isset($assertion) ? $assertion : '',
  259. 'expected' => $matches[3],
  260. 'origMethodName' => $origMethodName,
  261. 'className' => $this->inClassName['fullyQualifiedClassName'],
  262. 'methodName' => $methodName
  263. )
  264. );
  265. $methods .= $methodTemplate->render();
  266. $assertAnnotationFound = TRUE;
  267. }
  268. }
  269. }
  270. if (!$assertAnnotationFound) {
  271. $methodTemplate = new PHPUnit_Util_Template(
  272. sprintf(
  273. '%s%sTemplate%sIncompleteTestMethod.tpl',
  274. dirname(__FILE__),
  275. DIRECTORY_SEPARATOR,
  276. DIRECTORY_SEPARATOR
  277. )
  278. );
  279. $methodTemplate->setVar(
  280. array(
  281. 'methodName' => ucfirst($method->getName())
  282. )
  283. );
  284. $incompleteMethods .= $methodTemplate->render();
  285. }
  286. }
  287. }
  288. $classTemplate = new PHPUnit_Util_Template(
  289. sprintf(
  290. '%s%sTemplate%sTestClass.tpl',
  291. dirname(__FILE__),
  292. DIRECTORY_SEPARATOR,
  293. DIRECTORY_SEPARATOR
  294. )
  295. );
  296. if ($this->inSourceFile != '<internal>') {
  297. $requireClassFile = sprintf(
  298. "\n\nrequire_once '%s';",
  299. $this->inSourceFile
  300. );
  301. } else {
  302. $requireClassFile = '';
  303. }
  304. if ($this->outClassName['namespace'] != '') {
  305. $namespace = "\nnamespace " .
  306. $this->outClassName['namespace'] . ";\n";
  307. } else {
  308. $namespace = '';
  309. }
  310. $classTemplate->setVar(
  311. array(
  312. 'namespace' => $namespace,
  313. 'namespaceSeparator' => !empty($namespace) ? '\\' : '',
  314. 'className' => $this->inClassName['className'],
  315. 'testClassName' => $this->outClassName['className'],
  316. 'requireClassFile' => $requireClassFile,
  317. 'methods' => $methods . $incompleteMethods,
  318. 'date' => date('Y-m-d'),
  319. 'time' => date('H:i:s')
  320. )
  321. );
  322. if (!$verbose) {
  323. return $classTemplate->render();
  324. } else {
  325. return array(
  326. 'code' => $classTemplate->render(),
  327. 'incomplete' => empty($methods)
  328. );
  329. }
  330. }
  331. }
  332. ?>