CodeCoverageTest.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of the php-code-coverage package.
  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\CodeCoverage;
  11. use SebastianBergmann\CodeCoverage\Driver\Driver;
  12. use SebastianBergmann\Environment\Runtime;
  13. /**
  14. * @covers SebastianBergmann\CodeCoverage\CodeCoverage
  15. */
  16. class CodeCoverageTest extends TestCase
  17. {
  18. /**
  19. * @var CodeCoverage
  20. */
  21. private $coverage;
  22. protected function setUp(): void
  23. {
  24. $runtime = new Runtime;
  25. if (!$runtime->canCollectCodeCoverage()) {
  26. $this->markTestSkipped('No code coverage driver available');
  27. }
  28. $this->coverage = new CodeCoverage;
  29. }
  30. public function testCannotStopWithInvalidSecondArgument(): void
  31. {
  32. $this->expectException(Exception::class);
  33. $this->coverage->stop(true, null);
  34. }
  35. public function testCannotAppendWithInvalidArgument(): void
  36. {
  37. $this->expectException(Exception::class);
  38. $this->coverage->append([], null);
  39. }
  40. public function testCollect(): void
  41. {
  42. $coverage = $this->getCoverageForBankAccount();
  43. $this->assertEquals(
  44. $this->getExpectedDataArrayForBankAccount(),
  45. $coverage->getData()
  46. );
  47. $this->assertEquals(
  48. [
  49. 'BankAccountTest::testBalanceIsInitiallyZero' => ['size' => 'unknown', 'status' => -1],
  50. 'BankAccountTest::testBalanceCannotBecomeNegative' => ['size' => 'unknown', 'status' => -1],
  51. 'BankAccountTest::testBalanceCannotBecomeNegative2' => ['size' => 'unknown', 'status' => -1],
  52. 'BankAccountTest::testDepositWithdrawMoney' => ['size' => 'unknown', 'status' => -1],
  53. ],
  54. $coverage->getTests()
  55. );
  56. }
  57. public function testMerge(): void
  58. {
  59. $coverage = $this->getCoverageForBankAccountForFirstTwoTests();
  60. $coverage->merge($this->getCoverageForBankAccountForLastTwoTests());
  61. $this->assertEquals(
  62. $this->getExpectedDataArrayForBankAccount(),
  63. $coverage->getData()
  64. );
  65. }
  66. public function testMergeReverseOrder(): void
  67. {
  68. $coverage = $this->getCoverageForBankAccountForLastTwoTests();
  69. $coverage->merge($this->getCoverageForBankAccountForFirstTwoTests());
  70. $this->assertEquals(
  71. $this->getExpectedDataArrayForBankAccountInReverseOrder(),
  72. $coverage->getData()
  73. );
  74. }
  75. public function testMerge2(): void
  76. {
  77. $coverage = new CodeCoverage(
  78. $this->createMock(Driver::class),
  79. new Filter
  80. );
  81. $coverage->merge($this->getCoverageForBankAccount());
  82. $this->assertEquals(
  83. $this->getExpectedDataArrayForBankAccount(),
  84. $coverage->getData()
  85. );
  86. }
  87. public function testGetLinesToBeIgnored(): void
  88. {
  89. $this->assertEquals(
  90. [
  91. 1,
  92. 3,
  93. 4,
  94. 5,
  95. 7,
  96. 8,
  97. 9,
  98. 10,
  99. 11,
  100. 12,
  101. 13,
  102. 14,
  103. 15,
  104. 16,
  105. 17,
  106. 18,
  107. 19,
  108. 20,
  109. 21,
  110. 22,
  111. 23,
  112. 24,
  113. 25,
  114. 26,
  115. 27,
  116. 28,
  117. 30,
  118. 32,
  119. 33,
  120. 34,
  121. 35,
  122. 36,
  123. 37,
  124. 38,
  125. ],
  126. $this->getLinesToBeIgnored()->invoke(
  127. $this->coverage,
  128. TEST_FILES_PATH . 'source_with_ignore.php'
  129. )
  130. );
  131. }
  132. public function testGetLinesToBeIgnored2(): void
  133. {
  134. $this->assertEquals(
  135. [1, 5],
  136. $this->getLinesToBeIgnored()->invoke(
  137. $this->coverage,
  138. TEST_FILES_PATH . 'source_without_ignore.php'
  139. )
  140. );
  141. }
  142. public function testGetLinesToBeIgnored3(): void
  143. {
  144. $this->assertEquals(
  145. [
  146. 1,
  147. 2,
  148. 3,
  149. 4,
  150. 5,
  151. 8,
  152. 11,
  153. 15,
  154. 16,
  155. 19,
  156. 20,
  157. ],
  158. $this->getLinesToBeIgnored()->invoke(
  159. $this->coverage,
  160. TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php'
  161. )
  162. );
  163. }
  164. public function testGetLinesToBeIgnoredOneLineAnnotations(): void
  165. {
  166. $this->assertEquals(
  167. [
  168. 1,
  169. 2,
  170. 3,
  171. 4,
  172. 5,
  173. 6,
  174. 7,
  175. 8,
  176. 9,
  177. 10,
  178. 11,
  179. 14,
  180. 15,
  181. 16,
  182. 18,
  183. 20,
  184. 21,
  185. 23,
  186. 24,
  187. 25,
  188. 27,
  189. 28,
  190. 29,
  191. 30,
  192. 31,
  193. 32,
  194. 33,
  195. 34,
  196. 37,
  197. ],
  198. $this->getLinesToBeIgnored()->invoke(
  199. $this->coverage,
  200. TEST_FILES_PATH . 'source_with_oneline_annotations.php'
  201. )
  202. );
  203. }
  204. public function testGetLinesToBeIgnoredWhenIgnoreIsDisabled(): void
  205. {
  206. $this->coverage->setDisableIgnoredLines(true);
  207. $this->assertEquals(
  208. [
  209. 7,
  210. 11,
  211. 12,
  212. 13,
  213. 16,
  214. 17,
  215. 18,
  216. 19,
  217. 20,
  218. 21,
  219. 22,
  220. 23,
  221. 26,
  222. 27,
  223. 32,
  224. 33,
  225. 34,
  226. 35,
  227. 36,
  228. 37,
  229. ],
  230. $this->getLinesToBeIgnored()->invoke(
  231. $this->coverage,
  232. TEST_FILES_PATH . 'source_with_ignore.php'
  233. )
  234. );
  235. }
  236. public function testUseStatementsAreIgnored(): void
  237. {
  238. $this->assertEquals(
  239. [
  240. 1,
  241. 2,
  242. 3,
  243. 4,
  244. 5,
  245. 6,
  246. 7,
  247. 8,
  248. 9,
  249. 10,
  250. 13,
  251. 16,
  252. 23,
  253. 24,
  254. ],
  255. $this->getLinesToBeIgnored()->invoke(
  256. $this->coverage,
  257. TEST_FILES_PATH . 'source_with_use_statements.php'
  258. )
  259. );
  260. }
  261. public function testAppendThrowsExceptionIfCoveredCodeWasNotExecuted(): void
  262. {
  263. $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
  264. $this->coverage->setCheckForUnexecutedCoveredCode(true);
  265. $data = [
  266. TEST_FILES_PATH . 'BankAccount.php' => [
  267. 29 => -1,
  268. 31 => -1,
  269. ],
  270. ];
  271. $linesToBeCovered = [
  272. TEST_FILES_PATH . 'BankAccount.php' => [
  273. 22,
  274. 24,
  275. ],
  276. ];
  277. $linesToBeUsed = [];
  278. $this->expectException(CoveredCodeNotExecutedException::class);
  279. $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
  280. }
  281. public function testAppendThrowsExceptionIfUsedCodeWasNotExecuted(): void
  282. {
  283. $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
  284. $this->coverage->setCheckForUnexecutedCoveredCode(true);
  285. $data = [
  286. TEST_FILES_PATH . 'BankAccount.php' => [
  287. 29 => -1,
  288. 31 => -1,
  289. ],
  290. ];
  291. $linesToBeCovered = [
  292. TEST_FILES_PATH . 'BankAccount.php' => [
  293. 29,
  294. 31,
  295. ],
  296. ];
  297. $linesToBeUsed = [
  298. TEST_FILES_PATH . 'BankAccount.php' => [
  299. 22,
  300. 24,
  301. ],
  302. ];
  303. $this->expectException(CoveredCodeNotExecutedException::class);
  304. $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
  305. }
  306. /**
  307. * @return \ReflectionMethod
  308. */
  309. private function getLinesToBeIgnored()
  310. {
  311. $getLinesToBeIgnored = new \ReflectionMethod(
  312. 'SebastianBergmann\CodeCoverage\CodeCoverage',
  313. 'getLinesToBeIgnored'
  314. );
  315. $getLinesToBeIgnored->setAccessible(true);
  316. return $getLinesToBeIgnored;
  317. }
  318. }