CodeCoverageTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  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. if (version_compare(\PHPUnit_Runner_Version::id(), '4.7', '>=')) {
  253. $size = 'unknown';
  254. } else {
  255. $size = 'small';
  256. }
  257. $this->assertEquals(
  258. [
  259. 'BankAccountTest::testBalanceIsInitiallyZero' => ['size' => $size, 'status' => null],
  260. 'BankAccountTest::testBalanceCannotBecomeNegative' => ['size' => $size, 'status' => null],
  261. 'BankAccountTest::testBalanceCannotBecomeNegative2' => ['size' => $size, 'status' => null],
  262. 'BankAccountTest::testDepositWithdrawMoney' => ['size' => $size, 'status' => null]
  263. ],
  264. $coverage->getTests()
  265. );
  266. }
  267. public function testMerge()
  268. {
  269. $coverage = $this->getCoverageForBankAccountForFirstTwoTests();
  270. $coverage->merge($this->getCoverageForBankAccountForLastTwoTests());
  271. $this->assertEquals(
  272. $this->getExpectedDataArrayForBankAccount(),
  273. $coverage->getData()
  274. );
  275. }
  276. public function testMerge2()
  277. {
  278. $coverage = new CodeCoverage(
  279. $this->createMock(Xdebug::class),
  280. new Filter
  281. );
  282. $coverage->merge($this->getCoverageForBankAccount());
  283. $this->assertEquals(
  284. $this->getExpectedDataArrayForBankAccount(),
  285. $coverage->getData()
  286. );
  287. }
  288. public function testGetLinesToBeIgnored()
  289. {
  290. $this->assertEquals(
  291. [
  292. 1,
  293. 3,
  294. 4,
  295. 5,
  296. 7,
  297. 8,
  298. 9,
  299. 10,
  300. 11,
  301. 12,
  302. 13,
  303. 14,
  304. 15,
  305. 16,
  306. 17,
  307. 18,
  308. 19,
  309. 20,
  310. 21,
  311. 22,
  312. 23,
  313. 24,
  314. 25,
  315. 26,
  316. 27,
  317. 28,
  318. 30,
  319. 32,
  320. 33,
  321. 34,
  322. 35,
  323. 36,
  324. 37,
  325. 38
  326. ],
  327. $this->getLinesToBeIgnored()->invoke(
  328. $this->coverage,
  329. TEST_FILES_PATH . 'source_with_ignore.php'
  330. )
  331. );
  332. }
  333. public function testGetLinesToBeIgnored2()
  334. {
  335. $this->assertEquals(
  336. [1, 5],
  337. $this->getLinesToBeIgnored()->invoke(
  338. $this->coverage,
  339. TEST_FILES_PATH . 'source_without_ignore.php'
  340. )
  341. );
  342. }
  343. public function testGetLinesToBeIgnored3()
  344. {
  345. $this->assertEquals(
  346. [
  347. 1,
  348. 2,
  349. 3,
  350. 4,
  351. 5,
  352. 8,
  353. 11,
  354. 15,
  355. 16,
  356. 19,
  357. 20
  358. ],
  359. $this->getLinesToBeIgnored()->invoke(
  360. $this->coverage,
  361. TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php'
  362. )
  363. );
  364. }
  365. public function testGetLinesToBeIgnoredOneLineAnnotations()
  366. {
  367. $this->assertEquals(
  368. [
  369. 1,
  370. 2,
  371. 3,
  372. 4,
  373. 5,
  374. 6,
  375. 7,
  376. 8,
  377. 9,
  378. 10,
  379. 11,
  380. 12,
  381. 13,
  382. 14,
  383. 15,
  384. 16,
  385. 18,
  386. 20,
  387. 21,
  388. 23,
  389. 24,
  390. 25,
  391. 27,
  392. 28,
  393. 29,
  394. 30,
  395. 31,
  396. 32,
  397. 33,
  398. 34,
  399. 37
  400. ],
  401. $this->getLinesToBeIgnored()->invoke(
  402. $this->coverage,
  403. TEST_FILES_PATH . 'source_with_oneline_annotations.php'
  404. )
  405. );
  406. }
  407. /**
  408. * @return \ReflectionMethod
  409. */
  410. private function getLinesToBeIgnored()
  411. {
  412. $getLinesToBeIgnored = new \ReflectionMethod(
  413. 'SebastianBergmann\CodeCoverage\CodeCoverage',
  414. 'getLinesToBeIgnored'
  415. );
  416. $getLinesToBeIgnored->setAccessible(true);
  417. return $getLinesToBeIgnored;
  418. }
  419. public function testGetLinesToBeIgnoredWhenIgnoreIsDisabled()
  420. {
  421. $this->coverage->setDisableIgnoredLines(true);
  422. $this->assertEquals(
  423. [],
  424. $this->getLinesToBeIgnored()->invoke(
  425. $this->coverage,
  426. TEST_FILES_PATH . 'source_with_ignore.php'
  427. )
  428. );
  429. }
  430. /**
  431. * @expectedException SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
  432. */
  433. public function testAppendThrowsExceptionIfCoveredCodeWasNotExecuted()
  434. {
  435. $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
  436. $this->coverage->setCheckForUnexecutedCoveredCode(true);
  437. $data = [
  438. TEST_FILES_PATH . 'BankAccount.php' => [
  439. 29 => -1,
  440. 31 => -1
  441. ]
  442. ];
  443. $linesToBeCovered = [
  444. TEST_FILES_PATH . 'BankAccount.php' => [
  445. 22,
  446. 24
  447. ]
  448. ];
  449. $linesToBeUsed = [];
  450. $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
  451. }
  452. /**
  453. * @expectedException SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
  454. */
  455. public function testAppendThrowsExceptionIfUsedCodeWasNotExecuted()
  456. {
  457. $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
  458. $this->coverage->setCheckForUnexecutedCoveredCode(true);
  459. $data = [
  460. TEST_FILES_PATH . 'BankAccount.php' => [
  461. 29 => -1,
  462. 31 => -1
  463. ]
  464. ];
  465. $linesToBeCovered = [
  466. TEST_FILES_PATH . 'BankAccount.php' => [
  467. 29,
  468. 31
  469. ]
  470. ];
  471. $linesToBeUsed = [
  472. TEST_FILES_PATH . 'BankAccount.php' => [
  473. 22,
  474. 24
  475. ]
  476. ];
  477. $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
  478. }
  479. }