PageRenderTime 83ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/unit/AnalyserTest.php

https://github.com/sebastianbergmann/phploc
PHP | 407 lines | 335 code | 40 blank | 32 comment | 0 complexity | b80a8baa2f1ed81f99d3cf97dfd81015 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of PHPLOC.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace SebastianBergmann\PHPLOC;
  11. use const E_ALL;
  12. use function error_reporting;
  13. use function sprintf;
  14. use PHPUnit\Framework\TestCase;
  15. /**
  16. * @covers \SebastianBergmann\PHPLOC\Analyser
  17. */
  18. final class AnalyserTest extends TestCase
  19. {
  20. /**
  21. * @var Analyser
  22. */
  23. private $analyser;
  24. protected function setUp(): void
  25. {
  26. $this->analyser = new Analyser;
  27. }
  28. public function testWithoutTests(): void
  29. {
  30. $this->assertEqualsWithDelta(
  31. [
  32. 'files' => 1,
  33. 'loc' => 75,
  34. 'lloc' => 24,
  35. 'llocClasses' => 22,
  36. 'llocFunctions' => 1,
  37. 'llocGlobal' => 1,
  38. 'cloc' => 7,
  39. 'ccn' => 2,
  40. 'ccnMethods' => 2,
  41. 'interfaces' => 1,
  42. 'traits' => 0,
  43. 'classes' => 2,
  44. 'abstractClasses' => 1,
  45. 'concreteClasses' => 1,
  46. 'nonFinalClasses' => 1,
  47. 'finalClasses' => 0,
  48. 'functions' => 2,
  49. 'namedFunctions' => 1,
  50. 'anonymousFunctions' => 1,
  51. 'methods' => 4,
  52. 'publicMethods' => 2,
  53. 'nonPublicMethods' => 2,
  54. 'protectedMethods' => 1,
  55. 'privateMethods' => 1,
  56. 'nonStaticMethods' => 3,
  57. 'staticMethods' => 1,
  58. 'constants' => 2,
  59. 'classConstants' => 1,
  60. 'publicClassConstants' => 1,
  61. 'nonPublicClassConstants' => 0,
  62. 'globalConstants' => 1,
  63. 'testClasses' => 0,
  64. 'testMethods' => 0,
  65. 'ccnByLloc' => 0.08,
  66. 'llocByNof' => 0.5,
  67. 'methodCalls' => 6,
  68. 'staticMethodCalls' => 4,
  69. 'instanceMethodCalls' => 2,
  70. 'attributeAccesses' => 6,
  71. 'staticAttributeAccesses' => 4,
  72. 'instanceAttributeAccesses' => 2,
  73. 'globalAccesses' => 4,
  74. 'globalVariableAccesses' => 2,
  75. 'superGlobalVariableAccesses' => 1,
  76. 'globalConstantAccesses' => 1,
  77. 'directories' => 0,
  78. 'namespaces' => 1,
  79. 'ncloc' => 68,
  80. 'classCcnMin' => 1,
  81. 'classCcnAvg' => 1.65,
  82. 'classCcnMax' => 3,
  83. 'methodCcnMin' => 1,
  84. 'methodCcnAvg' => 1.65,
  85. 'methodCcnMax' => 2,
  86. 'classLlocMin' => 0,
  87. 'classLlocAvg' => 7.3,
  88. 'classLlocMax' => 22,
  89. 'methodLlocMin' => 4,
  90. 'methodLlocAvg' => 5.6,
  91. 'methodLlocMax' => 7,
  92. 'averageMethodsPerClass' => 1.33,
  93. 'minimumMethodsPerClass' => 0,
  94. 'maximumMethodsPerClass' => 4,
  95. ],
  96. $this->analyser->countFiles(
  97. [__DIR__ . '/../_files/source.php'],
  98. false
  99. ),
  100. 0.1
  101. );
  102. }
  103. public function testWithTests(): void
  104. {
  105. $this->assertEqualsWithDelta(
  106. [
  107. 'files' => 2,
  108. 'loc' => 98,
  109. 'lloc' => 24,
  110. 'llocClasses' => 22,
  111. 'llocFunctions' => 1,
  112. 'llocGlobal' => 1,
  113. 'cloc' => 11,
  114. 'ccn' => 2,
  115. 'ccnMethods' => 2,
  116. 'interfaces' => 1,
  117. 'traits' => 0,
  118. 'classes' => 2,
  119. 'abstractClasses' => 1,
  120. 'concreteClasses' => 1,
  121. 'nonFinalClasses' => 1,
  122. 'finalClasses' => 0,
  123. 'functions' => 2,
  124. 'namedFunctions' => 1,
  125. 'anonymousFunctions' => 1,
  126. 'methods' => 4,
  127. 'publicMethods' => 2,
  128. 'nonPublicMethods' => 2,
  129. 'protectedMethods' => 1,
  130. 'privateMethods' => 1,
  131. 'nonStaticMethods' => 3,
  132. 'staticMethods' => 1,
  133. 'constants' => 2,
  134. 'publicClassConstants' => 1,
  135. 'nonPublicClassConstants' => 0,
  136. 'classConstants' => 1,
  137. 'globalConstants' => 1,
  138. 'testClasses' => 1,
  139. 'testMethods' => 2,
  140. 'ccnByLloc' => 0.08,
  141. 'llocByNof' => 0.5,
  142. 'methodCalls' => 6,
  143. 'staticMethodCalls' => 4,
  144. 'instanceMethodCalls' => 2,
  145. 'attributeAccesses' => 6,
  146. 'staticAttributeAccesses' => 4,
  147. 'instanceAttributeAccesses' => 2,
  148. 'globalAccesses' => 4,
  149. 'globalVariableAccesses' => 2,
  150. 'superGlobalVariableAccesses' => 1,
  151. 'globalConstantAccesses' => 1,
  152. 'directories' => 0,
  153. 'namespaces' => 1,
  154. 'ncloc' => 87,
  155. 'classCcnMin' => 1,
  156. 'classCcnAvg' => 1.5,
  157. 'classCcnMax' => 3,
  158. 'methodCcnMin' => 1,
  159. 'methodCcnAvg' => 1.66,
  160. 'methodCcnMax' => 2,
  161. 'classLlocMin' => 0,
  162. 'classLlocAvg' => 5.5,
  163. 'classLlocMax' => 22,
  164. 'methodLlocMin' => 4,
  165. 'methodLlocAvg' => 5.6,
  166. 'methodLlocMax' => 7,
  167. 'averageMethodsPerClass' => 1,
  168. 'minimumMethodsPerClass' => 0,
  169. 'maximumMethodsPerClass' => 4,
  170. ],
  171. $this->analyser->countFiles(
  172. [
  173. __DIR__ . '/../_files/source.php',
  174. __DIR__ . '/../_files/tests.php',
  175. ],
  176. true
  177. ),
  178. 0.1
  179. );
  180. }
  181. public function testFilesThatExtendPHPUnitTestCaseAreCountedAsTests(): void
  182. {
  183. $result = $this->analyser->countFiles(
  184. [
  185. __DIR__ . '/../_files/tests.php',
  186. ],
  187. true
  188. );
  189. $this->assertSame(1, $result['testClasses']);
  190. }
  191. public function testFilesThatExtendPHPUnitTestCaseAreCountedAsTests2(): void
  192. {
  193. $result = $this->analyser->countFiles(
  194. [
  195. __DIR__ . '/../_files/tests_old.php',
  196. ],
  197. true
  198. );
  199. $this->assertSame(1, $result['testClasses']);
  200. }
  201. public function testFilesThatIndirectlyExtendPHPUnitTestCaseAreCountedAsTests(): void
  202. {
  203. $result = $this->analyser->countFiles(
  204. [
  205. __DIR__ . '/../_files/twoTestsThatIndirectlyExtendOldPHPUnitTestCase.php',
  206. ],
  207. true
  208. );
  209. $this->assertSame(3, $result['testClasses']);
  210. }
  211. public function testFilesThatIndirectlyExtendPHPUnitTestCaseAreCountedAsTests2(): void
  212. {
  213. $result = $this->analyser->countFiles(
  214. [
  215. __DIR__ . '/../_files/twoTestsThatIndirectlyExtendPHPUnitTestCase.php',
  216. ],
  217. true
  218. );
  219. $this->assertSame(3, $result['testClasses']);
  220. }
  221. public function testTraitsAreCountedCorrectly(): void
  222. {
  223. $result = $this->analyser->countFiles(
  224. [
  225. __DIR__ . '/../_files/trait.php',
  226. ],
  227. false
  228. );
  229. $this->assertSame(1, $result['traits']);
  230. }
  231. /**
  232. * @ticket 64
  233. */
  234. public function testIssue64IsFixed(): void
  235. {
  236. $result = $this->analyser->countFiles(
  237. [
  238. __DIR__ . '/../_files/issue_62.php',
  239. ],
  240. false
  241. );
  242. $this->assertSame(1, $result['cloc']);
  243. }
  244. /**
  245. * @ticket 112
  246. */
  247. public function testIssue112IsFixed(): void
  248. {
  249. $result = $this->analyser->countFiles(
  250. [
  251. __DIR__ . '/../_files/issue_112.php',
  252. ],
  253. false
  254. );
  255. $this->assertSame(5, $result['loc']);
  256. }
  257. /**
  258. * @ticket 126
  259. * @dataProvider issue126Provider
  260. */
  261. public function testIssue126IsFixed($fileNumber, $cloc): void
  262. {
  263. $file = __DIR__ . '/../_files/issue_126/issue_126_' . $fileNumber . '.php';
  264. $result = $this->analyser->countFiles([$file], false);
  265. $assertString = sprintf(
  266. 'Failed asserting that %s matches expected %s in issue_126_%d.php',
  267. $result['cloc'],
  268. $cloc,
  269. $fileNumber
  270. );
  271. $this->assertSame($cloc, $result['cloc'], $assertString);
  272. }
  273. public function issue126Provider()
  274. {
  275. // issue_126_X.php => CLOC
  276. return [
  277. [1, 1],
  278. [2, 1],
  279. [3, 1],
  280. [4, 2],
  281. [5, 3],
  282. [6, 3],
  283. [7, 3],
  284. ];
  285. }
  286. /**
  287. * @requires PHP 7
  288. * @ticket 138
  289. */
  290. public function testIssue138IsFixed(): void
  291. {
  292. error_reporting(E_ALL);
  293. $result = $this->analyser->countFiles(
  294. [
  295. __DIR__ . '/../_files/issue_138.php',
  296. ],
  297. false
  298. );
  299. $this->assertSame(1, $result['classes']);
  300. }
  301. /**
  302. * @ticket 139
  303. */
  304. public function testIssue139IsFixed(): void
  305. {
  306. error_reporting(E_ALL);
  307. $result = $this->analyser->countFiles(
  308. [
  309. __DIR__ . '/../_files/issue_139.php',
  310. ],
  311. false
  312. );
  313. $this->assertSame(1, $result['anonymousFunctions']);
  314. }
  315. public function testDeclareIsNotLogicalLine(): void
  316. {
  317. $result = $this->analyser->countFiles([__DIR__ . '/../_files/with_declare.php'], false);
  318. $this->assertSame(0, $result['llocGlobal']);
  319. }
  320. public function testNamespaceIsNotLogicalLine(): void
  321. {
  322. $result = $this->analyser->countFiles([__DIR__ . '/../_files/with_namespace.php'], false);
  323. $this->assertSame(0, $result['llocGlobal']);
  324. }
  325. public function testImportIsNotLogicalLine(): void
  326. {
  327. $result = $this->analyser->countFiles([__DIR__ . '/../_files/with_import.php'], false);
  328. $this->assertSame(0, $result['llocGlobal']);
  329. }
  330. public function test_it_makes_a_distinction_between_public_and_non_public_class_constants(): void
  331. {
  332. $result = $this->analyser->countFiles([__DIR__ . '/../_files/class_constants.php'], false);
  333. $this->assertSame(2, $result['publicClassConstants']);
  334. $this->assertSame(3, $result['nonPublicClassConstants']);
  335. $this->assertSame(5, $result['classConstants']);
  336. $this->assertSame(5, $result['constants']);
  337. }
  338. public function test_it_collects_the_number_of_final_non_final_and_abstract_classes(): void
  339. {
  340. $result = $this->analyser->countFiles([__DIR__ . '/../_files/classes.php'], false);
  341. $this->assertSame(9, $result['classes']);
  342. $this->assertSame(2, $result['finalClasses']);
  343. $this->assertSame(3, $result['nonFinalClasses']);
  344. $this->assertSame(4, $result['abstractClasses']);
  345. }
  346. public function test_it_makes_a_distinction_between_protected_and_private_methods(): void
  347. {
  348. $result = $this->analyser->countFiles([__DIR__ . '/../_files/methods.php'], false);
  349. $this->assertSame(2, $result['publicMethods']);
  350. $this->assertSame(1, $result['protectedMethods']);
  351. $this->assertSame(3, $result['privateMethods']);
  352. $this->assertSame(6, $result['methods']);
  353. }
  354. public function test_it_provides_average_minimum_and_maximum_number_of_methods_per_class(): void
  355. {
  356. $result = $this->analyser->countFiles([__DIR__ . '/../_files/methods_per_class.php'], false);
  357. $this->assertSame(2, $result['averageMethodsPerClass']);
  358. $this->assertSame(0, $result['minimumMethodsPerClass']);
  359. $this->assertSame(4, $result['maximumMethodsPerClass']);
  360. }
  361. public function test_use_trait_is_not_counted_as_logical_line(): void
  362. {
  363. $result = $this->analyser->countFiles([__DIR__ . '/../_files/class_using_trait.php'], false);
  364. $this->assertSame(1, $result['lloc']);
  365. $this->assertSame(1, $result['llocClasses']);
  366. }
  367. }