CodeCoverageTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. <?php
  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. require __DIR__ . '/../_files/BankAccount.php';
  12. require __DIR__ . '/../_files/BankAccountTest.php';
  13. use SebastianBergmann\CodeCoverage\Driver\Driver;
  14. use SebastianBergmann\CodeCoverage\Driver\PHPDBG;
  15. use SebastianBergmann\CodeCoverage\Driver\Xdebug;
  16. /**
  17. * @covers SebastianBergmann\CodeCoverage\CodeCoverage
  18. */
  19. class CodeCoverageTest extends TestCase
  20. {
  21. /**
  22. * @var CodeCoverage
  23. */
  24. private $coverage;
  25. protected function setUp()
  26. {
  27. $this->coverage = new CodeCoverage;
  28. }
  29. public function testCanBeConstructedForXdebugWithoutGivenFilterObject()
  30. {
  31. if (PHP_SAPI == 'phpdbg') {
  32. $this->markTestSkipped('Requires PHP CLI and Xdebug');
  33. }
  34. $this->assertAttributeInstanceOf(
  35. Xdebug::class,
  36. 'driver',
  37. $this->coverage
  38. );
  39. $this->assertAttributeInstanceOf(
  40. Filter::class,
  41. 'filter',
  42. $this->coverage
  43. );
  44. }
  45. public function testCanBeConstructedForXdebugWithGivenFilterObject()
  46. {
  47. if (PHP_SAPI == 'phpdbg') {
  48. $this->markTestSkipped('Requires PHP CLI and Xdebug');
  49. }
  50. $filter = new Filter;
  51. $coverage = new CodeCoverage(null, $filter);
  52. $this->assertAttributeInstanceOf(
  53. Xdebug::class,
  54. 'driver',
  55. $coverage
  56. );
  57. $this->assertSame($filter, $coverage->filter());
  58. }
  59. public function testCanBeConstructedForPhpdbgWithoutGivenFilterObject()
  60. {
  61. if (PHP_SAPI != 'phpdbg') {
  62. $this->markTestSkipped('Requires PHPDBG');
  63. }
  64. $this->assertAttributeInstanceOf(
  65. PHPDBG::class,
  66. 'driver',
  67. $this->coverage
  68. );
  69. $this->assertAttributeInstanceOf(
  70. Filter::class,
  71. 'filter',
  72. $this->coverage
  73. );
  74. }
  75. public function testCanBeConstructedForPhpdbgWithGivenFilterObject()
  76. {
  77. if (PHP_SAPI != 'phpdbg') {
  78. $this->markTestSkipped('Requires PHPDBG');
  79. }
  80. $filter = new Filter;
  81. $coverage = new CodeCoverage(null, $filter);
  82. $this->assertAttributeInstanceOf(
  83. PHPDBG::class,
  84. 'driver',
  85. $coverage
  86. );
  87. $this->assertSame($filter, $coverage->filter());
  88. }
  89. public function testCannotStopWithInvalidSecondArgument()
  90. {
  91. $this->expectException(Exception::class);
  92. $this->coverage->stop(true, null);
  93. }
  94. public function testCannotAppendWithInvalidArgument()
  95. {
  96. $this->expectException(Exception::class);
  97. $this->coverage->append([], null);
  98. }
  99. public function testSetCacheTokens()
  100. {
  101. $this->coverage->setCacheTokens(true);
  102. $this->assertAttributeEquals(true, 'cacheTokens', $this->coverage);
  103. }
  104. public function testSetCheckForUnintentionallyCoveredCode()
  105. {
  106. $this->coverage->setCheckForUnintentionallyCoveredCode(true);
  107. $this->assertAttributeEquals(
  108. true,
  109. 'checkForUnintentionallyCoveredCode',
  110. $this->coverage
  111. );
  112. }
  113. public function testSetCheckForMissingCoversAnnotation()
  114. {
  115. $this->coverage->setCheckForMissingCoversAnnotation(true);
  116. $this->assertAttributeEquals(
  117. true,
  118. 'checkForMissingCoversAnnotation',
  119. $this->coverage
  120. );
  121. }
  122. public function testSetForceCoversAnnotation()
  123. {
  124. $this->coverage->setForceCoversAnnotation(true);
  125. $this->assertAttributeEquals(
  126. true,
  127. 'forceCoversAnnotation',
  128. $this->coverage
  129. );
  130. }
  131. public function testSetCheckForUnexecutedCoveredCode()
  132. {
  133. $this->coverage->setCheckForUnexecutedCoveredCode(true);
  134. $this->assertAttributeEquals(
  135. true,
  136. 'checkForUnexecutedCoveredCode',
  137. $this->coverage
  138. );
  139. }
  140. public function testSetAddUncoveredFilesFromWhitelist()
  141. {
  142. $this->coverage->setAddUncoveredFilesFromWhitelist(true);
  143. $this->assertAttributeEquals(
  144. true,
  145. 'addUncoveredFilesFromWhitelist',
  146. $this->coverage
  147. );
  148. }
  149. public function testSetProcessUncoveredFilesFromWhitelist()
  150. {
  151. $this->coverage->setProcessUncoveredFilesFromWhitelist(true);
  152. $this->assertAttributeEquals(
  153. true,
  154. 'processUncoveredFilesFromWhitelist',
  155. $this->coverage
  156. );
  157. }
  158. public function testSetIgnoreDeprecatedCode()
  159. {
  160. $this->coverage->setIgnoreDeprecatedCode(true);
  161. $this->assertAttributeEquals(
  162. true,
  163. 'ignoreDeprecatedCode',
  164. $this->coverage
  165. );
  166. }
  167. public function testClear()
  168. {
  169. $this->coverage->clear();
  170. $this->assertAttributeEquals(null, 'currentId', $this->coverage);
  171. $this->assertAttributeEquals([], 'data', $this->coverage);
  172. $this->assertAttributeEquals([], 'tests', $this->coverage);
  173. }
  174. public function testCollect()
  175. {
  176. $coverage = $this->getCoverageForBankAccount();
  177. $this->assertEquals(
  178. $this->getExpectedDataArrayForBankAccount(),
  179. $coverage->getData()
  180. );
  181. $this->assertEquals(
  182. [
  183. 'BankAccountTest::testBalanceIsInitiallyZero' => ['size' => 'unknown', 'status' => -1],
  184. 'BankAccountTest::testBalanceCannotBecomeNegative' => ['size' => 'unknown', 'status' => -1],
  185. 'BankAccountTest::testBalanceCannotBecomeNegative2' => ['size' => 'unknown', 'status' => -1],
  186. 'BankAccountTest::testDepositWithdrawMoney' => ['size' => 'unknown', 'status' => -1]
  187. ],
  188. $coverage->getTests()
  189. );
  190. }
  191. public function testMerge()
  192. {
  193. $coverage = $this->getCoverageForBankAccountForFirstTwoTests();
  194. $coverage->merge($this->getCoverageForBankAccountForLastTwoTests());
  195. $this->assertEquals(
  196. $this->getExpectedDataArrayForBankAccount(),
  197. $coverage->getData()
  198. );
  199. }
  200. public function testMergeReverseOrder()
  201. {
  202. $coverage = $this->getCoverageForBankAccountForLastTwoTests();
  203. $coverage->merge($this->getCoverageForBankAccountForFirstTwoTests());
  204. $this->assertEquals(
  205. $this->getExpectedDataArrayForBankAccountInReverseOrder(),
  206. $coverage->getData()
  207. );
  208. }
  209. public function testMerge2()
  210. {
  211. $coverage = new CodeCoverage(
  212. $this->createMock(Driver::class),
  213. new Filter
  214. );
  215. $coverage->merge($this->getCoverageForBankAccount());
  216. $this->assertEquals(
  217. $this->getExpectedDataArrayForBankAccount(),
  218. $coverage->getData()
  219. );
  220. }
  221. public function testGetLinesToBeIgnored()
  222. {
  223. $this->assertEquals(
  224. [
  225. 1,
  226. 3,
  227. 4,
  228. 5,
  229. 7,
  230. 8,
  231. 9,
  232. 10,
  233. 11,
  234. 12,
  235. 13,
  236. 14,
  237. 15,
  238. 16,
  239. 17,
  240. 18,
  241. 19,
  242. 20,
  243. 21,
  244. 22,
  245. 23,
  246. 24,
  247. 25,
  248. 26,
  249. 27,
  250. 28,
  251. 30,
  252. 32,
  253. 33,
  254. 34,
  255. 35,
  256. 36,
  257. 37,
  258. 38
  259. ],
  260. $this->getLinesToBeIgnored()->invoke(
  261. $this->coverage,
  262. TEST_FILES_PATH . 'source_with_ignore.php'
  263. )
  264. );
  265. }
  266. public function testGetLinesToBeIgnored2()
  267. {
  268. $this->assertEquals(
  269. [1, 5],
  270. $this->getLinesToBeIgnored()->invoke(
  271. $this->coverage,
  272. TEST_FILES_PATH . 'source_without_ignore.php'
  273. )
  274. );
  275. }
  276. public function testGetLinesToBeIgnored3()
  277. {
  278. $this->assertEquals(
  279. [
  280. 1,
  281. 2,
  282. 3,
  283. 4,
  284. 5,
  285. 8,
  286. 11,
  287. 15,
  288. 16,
  289. 19,
  290. 20
  291. ],
  292. $this->getLinesToBeIgnored()->invoke(
  293. $this->coverage,
  294. TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php'
  295. )
  296. );
  297. }
  298. public function testGetLinesToBeIgnoredOneLineAnnotations()
  299. {
  300. $this->assertEquals(
  301. [
  302. 1,
  303. 2,
  304. 3,
  305. 4,
  306. 5,
  307. 6,
  308. 7,
  309. 8,
  310. 9,
  311. 10,
  312. 11,
  313. 14,
  314. 15,
  315. 16,
  316. 18,
  317. 20,
  318. 21,
  319. 23,
  320. 24,
  321. 25,
  322. 27,
  323. 28,
  324. 29,
  325. 30,
  326. 31,
  327. 32,
  328. 33,
  329. 34,
  330. 37
  331. ],
  332. $this->getLinesToBeIgnored()->invoke(
  333. $this->coverage,
  334. TEST_FILES_PATH . 'source_with_oneline_annotations.php'
  335. )
  336. );
  337. }
  338. /**
  339. * @return \ReflectionMethod
  340. */
  341. private function getLinesToBeIgnored()
  342. {
  343. $getLinesToBeIgnored = new \ReflectionMethod(
  344. 'SebastianBergmann\CodeCoverage\CodeCoverage',
  345. 'getLinesToBeIgnored'
  346. );
  347. $getLinesToBeIgnored->setAccessible(true);
  348. return $getLinesToBeIgnored;
  349. }
  350. public function testGetLinesToBeIgnoredWhenIgnoreIsDisabled()
  351. {
  352. $this->coverage->setDisableIgnoredLines(true);
  353. $this->assertEquals(
  354. [
  355. 7,
  356. 11,
  357. 12,
  358. 13,
  359. 16,
  360. 17,
  361. 18,
  362. 19,
  363. 20,
  364. 21,
  365. 22,
  366. 23,
  367. 26,
  368. 27,
  369. 32,
  370. 33,
  371. 34,
  372. 35,
  373. 36,
  374. 37
  375. ],
  376. $this->getLinesToBeIgnored()->invoke(
  377. $this->coverage,
  378. TEST_FILES_PATH . 'source_with_ignore.php'
  379. )
  380. );
  381. }
  382. public function testAppendThrowsExceptionIfCoveredCodeWasNotExecuted()
  383. {
  384. $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
  385. $this->coverage->setCheckForUnexecutedCoveredCode(true);
  386. $data = [
  387. TEST_FILES_PATH . 'BankAccount.php' => [
  388. 29 => -1,
  389. 31 => -1
  390. ]
  391. ];
  392. $linesToBeCovered = [
  393. TEST_FILES_PATH . 'BankAccount.php' => [
  394. 22,
  395. 24
  396. ]
  397. ];
  398. $linesToBeUsed = [];
  399. $this->expectException(CoveredCodeNotExecutedException::class);
  400. $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
  401. }
  402. public function testAppendThrowsExceptionIfUsedCodeWasNotExecuted()
  403. {
  404. $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
  405. $this->coverage->setCheckForUnexecutedCoveredCode(true);
  406. $data = [
  407. TEST_FILES_PATH . 'BankAccount.php' => [
  408. 29 => -1,
  409. 31 => -1
  410. ]
  411. ];
  412. $linesToBeCovered = [
  413. TEST_FILES_PATH . 'BankAccount.php' => [
  414. 29,
  415. 31
  416. ]
  417. ];
  418. $linesToBeUsed = [
  419. TEST_FILES_PATH . 'BankAccount.php' => [
  420. 22,
  421. 24
  422. ]
  423. ];
  424. $this->expectException(CoveredCodeNotExecutedException::class);
  425. $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
  426. }
  427. }