1<?php 2/** 3 * PHP_CodeCoverage 4 * 5 * Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * * Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * * Neither the name of Sebastian Bergmann nor the names of his 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @category PHP 38 * @package CodeCoverage 39 * @subpackage Tests 40 * @author Sebastian Bergmann <sebastian@phpunit.de> 41 * @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de> 42 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License 43 * @link http://github.com/sebastianbergmann/php-code-coverage 44 * @since File available since Release 1.0.0 45 */ 46 47if (!defined('TEST_FILES_PATH')) { 48 define( 49 'TEST_FILES_PATH', 50 dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 51 '_files' . DIRECTORY_SEPARATOR 52 ); 53} 54 55require_once TEST_FILES_PATH . '../TestCase.php'; 56 57require_once TEST_FILES_PATH . 'BankAccount.php'; 58require_once TEST_FILES_PATH . 'BankAccountTest.php'; 59 60/** 61 * Tests for the PHP_CodeCoverage class. 62 * 63 * @category PHP 64 * @package CodeCoverage 65 * @subpackage Tests 66 * @author Sebastian Bergmann <sebastian@phpunit.de> 67 * @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de> 68 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License 69 * @link http://github.com/sebastianbergmann/php-code-coverage 70 * @since Class available since Release 1.0.0 71 */ 72class PHP_CodeCoverageTest extends PHP_CodeCoverage_TestCase 73{ 74 protected $coverage; 75 protected $getLinesToBeCovered; 76 77 protected function setUp() 78 { 79 $this->coverage = new PHP_CodeCoverage; 80 81 $this->getLinesToBeCovered = new ReflectionMethod( 82 'PHP_CodeCoverage', 'getLinesToBeCovered' 83 ); 84 85 $this->getLinesToBeCovered->setAccessible(TRUE); 86 } 87 88 /** 89 * @covers PHP_CodeCoverage::__construct 90 * @covers PHP_CodeCoverage::filter 91 */ 92 public function testConstructor() 93 { 94 $this->assertAttributeInstanceOf( 95 'PHP_CodeCoverage_Driver_Xdebug', 'driver', $this->coverage 96 ); 97 98 $this->assertAttributeInstanceOf( 99 'PHP_CodeCoverage_Filter', 'filter', $this->coverage 100 ); 101 } 102 103 /** 104 * @covers PHP_CodeCoverage::__construct 105 * @covers PHP_CodeCoverage::filter 106 */ 107 public function testConstructor2() 108 { 109 $filter = new PHP_CodeCoverage_Filter; 110 $coverage = new PHP_CodeCoverage(NULL, $filter); 111 112 $this->assertAttributeInstanceOf( 113 'PHP_CodeCoverage_Driver_Xdebug', 'driver', $coverage 114 ); 115 116 $this->assertSame($filter, $coverage->filter()); 117 } 118 119 /** 120 * @covers PHP_CodeCoverage::start 121 * @expectedException PHP_CodeCoverage_Exception 122 */ 123 public function testStartThrowsExceptionForInvalidArgument() 124 { 125 $this->coverage->start(NULL, array(), NULL); 126 } 127 128 /** 129 * @covers PHP_CodeCoverage::stop 130 * @expectedException PHP_CodeCoverage_Exception 131 */ 132 public function testStopThrowsExceptionForInvalidArgument() 133 { 134 $this->coverage->stop(NULL); 135 } 136 137 /** 138 * @covers PHP_CodeCoverage::append 139 * @expectedException PHP_CodeCoverage_Exception 140 */ 141 public function testAppendThrowsExceptionForInvalidArgument() 142 { 143 $this->coverage->append(array(), NULL); 144 } 145 146 /** 147 * @covers PHP_CodeCoverage::setCacheTokens 148 * @expectedException PHP_CodeCoverage_Exception 149 */ 150 public function testSetCacheTokensThrowsExceptionForInvalidArgument() 151 { 152 $this->coverage->setCacheTokens(NULL); 153 } 154 155 /** 156 * @covers PHP_CodeCoverage::setCacheTokens 157 */ 158 public function testSetCacheTokens() 159 { 160 $this->coverage->setCacheTokens(TRUE); 161 $this->assertAttributeEquals(TRUE, 'cacheTokens', $this->coverage); 162 } 163 164 /** 165 * @covers PHP_CodeCoverage::setForceCoversAnnotation 166 * @expectedException PHP_CodeCoverage_Exception 167 */ 168 public function testSetForceCoversAnnotationThrowsExceptionForInvalidArgument() 169 { 170 $this->coverage->setForceCoversAnnotation(NULL); 171 } 172 173 /** 174 * @covers PHP_CodeCoverage::setForceCoversAnnotation 175 */ 176 public function testSetForceCoversAnnotation() 177 { 178 $this->coverage->setForceCoversAnnotation(TRUE); 179 $this->assertAttributeEquals( 180 TRUE, 'forceCoversAnnotation', $this->coverage 181 ); 182 } 183 184 /** 185 * @covers PHP_CodeCoverage::setProcessUncoveredFilesFromWhitelist 186 * @expectedException PHP_CodeCoverage_Exception 187 */ 188 public function testSetProcessUncoveredFilesFromWhitelistThrowsExceptionForInvalidArgument() 189 { 190 $this->coverage->setProcessUncoveredFilesFromWhitelist(NULL); 191 } 192 193 /** 194 * @covers PHP_CodeCoverage::setProcessUncoveredFilesFromWhitelist 195 */ 196 public function testSetProcessUncoveredFilesFromWhitelist() 197 { 198 $this->coverage->setProcessUncoveredFilesFromWhitelist(TRUE); 199 $this->assertAttributeEquals( 200 TRUE, 'processUncoveredFilesFromWhitelist', $this->coverage 201 ); 202 } 203 204 /** 205 * @covers PHP_CodeCoverage::setMapTestClassNameToCoveredClassName 206 */ 207 public function testSetMapTestClassNameToCoveredClassName() 208 { 209 $this->coverage->setMapTestClassNameToCoveredClassName(TRUE); 210 $this->assertAttributeEquals( 211 TRUE, 'mapTestClassNameToCoveredClassName', $this->coverage 212 ); 213 } 214 215 /** 216 * @covers PHP_CodeCoverage::setMapTestClassNameToCoveredClassName 217 * @expectedException PHP_CodeCoverage_Exception 218 */ 219 public function testSetMapTestClassNameToCoveredClassNameThrowsExceptionForInvalidArgument() 220 { 221 $this->coverage->setMapTestClassNameToCoveredClassName(NULL); 222 } 223 224 /** 225 * @covers PHP_CodeCoverage::clear 226 */ 227 public function testClear() 228 { 229 $this->coverage->clear(); 230 231 $this->assertAttributeEquals(NULL, 'currentId', $this->coverage); 232 $this->assertAttributeEquals(array(), 'data', $this->coverage); 233 $this->assertAttributeEquals(array(), 'tests', $this->coverage); 234 } 235 236 /** 237 * @covers PHP_CodeCoverage::start 238 * @covers PHP_CodeCoverage::stop 239 * @covers PHP_CodeCoverage::append 240 * @covers PHP_CodeCoverage::applyListsFilter 241 * @covers PHP_CodeCoverage::initializeFilesThatAreSeenTheFirstTime 242 * @covers PHP_CodeCoverage::applyCoversAnnotationFilter 243 * @covers PHP_CodeCoverage::getTests 244 */ 245 public function testCollect() 246 { 247 $coverage = $this->getCoverageForBankAccount(); 248 249 $this->assertEquals( 250 $this->getExpectedDataArrayForBankAccount(), $coverage->getData() 251 ); 252 253 $this->assertEquals( 254 array( 255 'BankAccountTest::testBalanceIsInitiallyZero' => NULL, 256 'BankAccountTest::testBalanceCannotBecomeNegative' => NULL, 257 'BankAccountTest::testBalanceCannotBecomeNegative2' => NULL, 258 'BankAccountTest::testDepositWithdrawMoney' => NULL 259 ), 260 $coverage->getTests() 261 ); 262 } 263 264 /** 265 * @covers PHP_CodeCoverage::getData 266 * @covers PHP_CodeCoverage::merge 267 */ 268 public function testMerge() 269 { 270 $coverage = $this->getCoverageForBankAccountForFirstTwoTests(); 271 $coverage->merge($this->getCoverageForBankAccountForLastTwoTests()); 272 273 $this->assertEquals( 274 $this->getExpectedDataArrayForBankAccount(), $coverage->getData() 275 ); 276 } 277 278 /** 279 * @covers PHP_CodeCoverage::getData 280 * @covers PHP_CodeCoverage::merge 281 */ 282 public function testMerge2() 283 { 284 $coverage = new PHP_CodeCoverage( 285 $this->getMock('PHP_CodeCoverage_Driver_Xdebug'), 286 new PHP_CodeCoverage_Filter 287 ); 288 289 $coverage->merge($this->getCoverageForBankAccount()); 290 291 $this->assertEquals( 292 $this->getExpectedDataArrayForBankAccount(), $coverage->getData() 293 ); 294 } 295 296 /** 297 * @covers PHP_CodeCoverage::getLinesToBeCovered 298 * @covers PHP_CodeCoverage::resolveCoversToReflectionObjects 299 * @dataProvider getLinesToBeCoveredProvider 300 */ 301 public function testGetLinesToBeCovered($test, $lines) 302 { 303 if (strpos($test, 'Namespace') === 0) { 304 $expected = array( 305 TEST_FILES_PATH . 'NamespaceCoveredClass.php' => $lines 306 ); 307 } 308 309 else if ($test === 'CoverageNoneTest') { 310 $expected = array(); 311 } 312 313 else if ($test === 'CoverageNothingTest') { 314 $expected = false; 315 } 316 317 else if ($test === 'CoverageFunctionTest') { 318 $expected = array( 319 TEST_FILES_PATH . 'CoveredFunction.php' => $lines 320 ); 321 } 322 323 else { 324 $expected = array(TEST_FILES_PATH . 'CoveredClass.php' => $lines); 325 } 326 327 $this->assertEquals( 328 $expected, 329 $this->getLinesToBeCovered->invoke( 330 $this->coverage, $test, 'testSomething' 331 ) 332 ); 333 } 334 335 /** 336 * @covers PHP_CodeCoverage::getLinesToBeCovered 337 * @covers PHP_CodeCoverage::resolveCoversToReflectionObjects 338 * @expectedException PHP_CodeCoverage_Exception 339 */ 340 public function testGetLinesToBeCovered2() 341 { 342 $this->getLinesToBeCovered->invoke( 343 $this->coverage, 'NotExistingCoveredElementTest', 'testOne' 344 ); 345 } 346 347 /** 348 * @covers PHP_CodeCoverage::getLinesToBeCovered 349 * @covers PHP_CodeCoverage::resolveCoversToReflectionObjects 350 * @expectedException PHP_CodeCoverage_Exception 351 */ 352 public function testGetLinesToBeCovered3() 353 { 354 $this->getLinesToBeCovered->invoke( 355 $this->coverage, 'NotExistingCoveredElementTest', 'testTwo' 356 ); 357 } 358 359 /** 360 * @covers PHP_CodeCoverage::getLinesToBeCovered 361 * @covers PHP_CodeCoverage::resolveCoversToReflectionObjects 362 * @expectedException PHP_CodeCoverage_Exception 363 */ 364 public function testGetLinesToBeCovered4() 365 { 366 $this->getLinesToBeCovered->invoke( 367 $this->coverage, 'NotExistingCoveredElementTest', 'testThree' 368 ); 369 } 370 371 /** 372 * @covers PHP_CodeCoverage::getLinesToBeCovered 373 */ 374 public function testGetLinesToBeCoveredSkipsNonExistantMethods() 375 { 376 $this->assertSame( 377 array(), 378 $this->getLinesToBeCovered->invoke( 379 $this->coverage, 380 'NotExistingCoveredElementTest', 381 'methodDoesNotExist' 382 ) 383 ); 384 } 385 386 /** 387 * @covers PHP_CodeCoverage::getLinesToBeCovered 388 * @expectedException PHP_CodeCoverage_Exception 389 */ 390 public function testTwoCoversDefaultClassAnnoationsAreNotAllowed() 391 { 392 $this->getLinesToBeCovered->invoke( 393 $this->coverage, 394 'CoverageTwoDefaultClassAnnotations', 395 'testSomething' 396 ); 397 } 398 399 /** 400 * @covers PHP_CodeCoverage::getLinesToBeCovered 401 */ 402 public function testFunctionParenthesesAreAllowed() 403 { 404 $this->assertSame( 405 array(TEST_FILES_PATH . 'CoveredFunction.php' => range(2, 4)), 406 $this->getLinesToBeCovered->invoke( 407 $this->coverage, 408 'CoverageFunctionParenthesesTest', 409 'testSomething' 410 ) 411 ); 412 } 413 414 /** 415 * @covers PHP_CodeCoverage::getLinesToBeCovered 416 */ 417 public function testFunctionParenthesesAreAllowedWithWhitespace() 418 { 419 $this->assertSame( 420 array(TEST_FILES_PATH . 'CoveredFunction.php' => range(2, 4)), 421 $this->getLinesToBeCovered->invoke( 422 $this->coverage, 423 'CoverageFunctionParenthesesWhitespaceTest', 424 'testSomething' 425 ) 426 ); 427 } 428 429 /** 430 * @covers PHP_CodeCoverage::getLinesToBeCovered 431 */ 432 public function testMethodParenthesesAreAllowed() 433 { 434 $this->assertSame( 435 array(TEST_FILES_PATH . 'CoveredClass.php' => range(31, 35)), 436 $this->getLinesToBeCovered->invoke( 437 $this->coverage, 438 'CoverageMethodParenthesesTest', 439 'testSomething' 440 ) 441 ); 442 } 443 444 /** 445 * @covers PHP_CodeCoverage::getLinesToBeCovered 446 */ 447 public function testMethodParenthesesAreAllowedWithWhitespace() 448 { 449 $this->assertSame( 450 array(TEST_FILES_PATH . 'CoveredClass.php' => range(31, 35)), 451 $this->getLinesToBeCovered->invoke( 452 $this->coverage, 453 'CoverageMethodParenthesesWhitespaceTest', 454 'testSomething' 455 ) 456 ); 457 } 458 459 public function getLinesToBeCoveredProvider() 460 { 461 return array( 462 array( 463 'CoverageNoneTest', 464 array() 465 ), 466 array( 467 'CoverageClassExtendedTest', 468 array_merge(range(19, 36), range(2, 17)) 469 ), 470 array( 471 'CoverageClassTest', 472 range(19, 36) 473 ), 474 array( 475 'CoverageMethodTest', 476 range(31, 35) 477 ), 478 array( 479 'CoverageMethodOneLineAnnotationTest', 480 range(31, 35) 481 ), 482 array( 483 'CoverageNotPrivateTest', 484 array_merge(range(25, 29), range(31, 35)) 485 ), 486 array( 487 'CoverageNotProtectedTest', 488 array_merge(range(21, 23), range(31, 35)) 489 ), 490 array( 491 'CoverageNotPublicTest', 492 array_merge(range(21, 23), range(25, 29)) 493 ), 494 array( 495 'CoveragePrivateTest', 496 range(21, 23) 497 ), 498 array( 499 'CoverageProtectedTest', 500 range(25, 29) 501 ), 502 array( 503 'CoveragePublicTest', 504 range(31, 35) 505 ), 506 array( 507 'CoverageFunctionTest', 508 range(2, 4) 509 ), 510 array( 511 'NamespaceCoverageClassExtendedTest', 512 array_merge(range(21, 38), range(4, 19)) 513 ), 514 array( 515 'NamespaceCoverageClassTest', 516 range(21, 38) 517 ), 518 array( 519 'NamespaceCoverageMethodTest', 520 range(33, 37) 521 ), 522 array( 523 'NamespaceCoverageNotPrivateTest', 524 array_merge(range(27, 31), range(33, 37)) 525 ), 526 array( 527 'NamespaceCoverageNotProtectedTest', 528 array_merge(range(23, 25), range(33, 37)) 529 ), 530 array( 531 'NamespaceCoverageNotPublicTest', 532 array_merge(range(23, 25), range(27, 31)) 533 ), 534 array( 535 'NamespaceCoveragePrivateTest', 536 range(23, 25) 537 ), 538 array( 539 'NamespaceCoverageProtectedTest', 540 range(27, 31) 541 ), 542 array( 543 'NamespaceCoveragePublicTest', 544 range(33, 37) 545 ), 546 array( 547 'NamespaceCoverageCoversClassTest', 548 array_merge(range(23, 25), range(27, 31), range(33, 37), range(6, 8), range(10, 13), range(15, 18)) 549 ), 550 array( 551 'NamespaceCoverageCoversClassPublicTest', 552 range(33, 37) 553 ), 554 array( 555 'CoverageNothingTest', 556 false 557 ) 558 ); 559 } 560} 561