CodeCoverageTest.php 14 KB

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