Tests.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /**
  3. * PHPUnit testsuite for kohana application
  4. *
  5. * @package Kohana/UnitTest
  6. * @author Kohana Team
  7. * @author BRMatt <matthew@sigswitch.com>
  8. * @author Paul Banks
  9. * @copyright (c) Kohana Team
  10. * @license https://koseven.ga/LICENSE.md
  11. */
  12. class Kohana_Unittest_Tests {
  13. static protected $cache = [];
  14. /**
  15. * Loads test files if they cannot be found by kohana
  16. * @param <type> $class
  17. */
  18. static function autoload($class)
  19. {
  20. $file = str_replace('_', '/', $class);
  21. if ($file = Kohana::find_file('tests', $file))
  22. {
  23. require_once $file;
  24. }
  25. }
  26. /**
  27. * Configures the environment for testing
  28. *
  29. * Does the following:
  30. *
  31. * * Loads the phpunit framework (for the web ui)
  32. * * Restores exception phpunit error handlers (for cli)
  33. * * registeres an autoloader to load test files
  34. */
  35. static public function configure_environment()
  36. {
  37. restore_exception_handler();
  38. restore_error_handler();
  39. spl_autoload_register(['Unittest_tests', 'autoload']);
  40. }
  41. /**
  42. * Creates the test suite for kohana
  43. *
  44. * @return Unittest_TestSuite
  45. */
  46. static function suite()
  47. {
  48. static $suite = NULL;
  49. if ($suite instanceof PHPUnit_Framework_TestSuite)
  50. {
  51. return $suite;
  52. }
  53. Unittest_Tests::configure_environment();
  54. $suite = new Unittest_TestSuite;
  55. // Load the whitelist and blacklist for code coverage
  56. $config = Kohana::$config->load('unittest');
  57. if ($config->use_whitelist)
  58. {
  59. Unittest_Tests::whitelist(NULL, $suite);
  60. }
  61. // Add tests
  62. $files = Kohana::list_files('tests');
  63. self::addTests($suite, $files);
  64. return $suite;
  65. }
  66. /**
  67. * Add files to test suite $suite
  68. *
  69. * Uses recursion to scan subdirectories
  70. *
  71. * @param Unittest_TestSuite $suite The test suite to add to
  72. * @param array $files Array of files to test
  73. */
  74. static function addTests(Unittest_TestSuite $suite, array $files)
  75. {
  76. foreach ($files as $path => $file)
  77. {
  78. if (is_array($file))
  79. {
  80. if ($path != 'tests'.DIRECTORY_SEPARATOR.'test_data')
  81. {
  82. self::addTests($suite, $file);
  83. }
  84. }
  85. else
  86. {
  87. // Make sure we only include php files
  88. if (is_file($file) AND substr($file, -strlen(EXT)) === EXT)
  89. {
  90. // The default PHPUnit TestCase extension
  91. if ( ! strpos($file, 'TestCase'.EXT))
  92. {
  93. $suite->addTestFile($file);
  94. }
  95. else
  96. {
  97. require_once($file);
  98. }
  99. }
  100. }
  101. }
  102. }
  103. /**
  104. * Sets the whitelist
  105. *
  106. * If no directories are provided then the function'll load the whitelist
  107. * set in the config file
  108. *
  109. * @param array $directories Optional directories to whitelist
  110. * @param Unittest_Testsuite $suite Suite to load the whitelist into
  111. */
  112. static public function whitelist(array $directories = NULL, Unittest_TestSuite $suite = NULL)
  113. {
  114. if (empty($directories))
  115. {
  116. $directories = self::get_config_whitelist();
  117. }
  118. if (count($directories))
  119. {
  120. foreach ($directories as & $directory)
  121. {
  122. $directory = realpath($directory).'/';
  123. }
  124. // Only whitelist the "top" files in the cascading filesystem
  125. self::set_whitelist(Kohana::list_files('classes', $directories), $suite);
  126. }
  127. }
  128. /**
  129. * Works out the whitelist from the config
  130. * Used only on the CLI
  131. *
  132. * @returns array Array of directories to whitelist
  133. */
  134. static protected function get_config_whitelist()
  135. {
  136. $config = Kohana::$config->load('unittest');
  137. $directories = [];
  138. if ($config->whitelist['app'])
  139. {
  140. $directories['k_app'] = APPPATH;
  141. }
  142. if ($modules = $config->whitelist['modules'])
  143. {
  144. $k_modules = Kohana::modules();
  145. // Have to do this because kohana merges config...
  146. // If you want to include all modules & override defaults then TRUE must be the first
  147. // value in the modules array of your app/config/unittest file
  148. if (array_search(TRUE, $modules, TRUE) === (count($modules) - 1))
  149. {
  150. $modules = $k_modules;
  151. }
  152. elseif (array_search(FALSE, $modules, TRUE) === FALSE)
  153. {
  154. $modules = array_intersect_key($k_modules, array_combine($modules, $modules));
  155. }
  156. else
  157. {
  158. // modules are disabled
  159. $modules = [];
  160. }
  161. $directories += $modules;
  162. }
  163. if ($config->whitelist['system'])
  164. {
  165. $directories['k_sys'] = SYSPATH;
  166. }
  167. return $directories;
  168. }
  169. /**
  170. * Recursively whitelists an array of files
  171. *
  172. * @param array $files Array of files to whitelist
  173. * @param Unittest_TestSuite $suite Suite to load the whitelist into
  174. */
  175. static protected function set_whitelist($files, Unittest_TestSuite $suite = NULL)
  176. {
  177. foreach ($files as $file)
  178. {
  179. if (is_array($file))
  180. {
  181. self::set_whitelist($file, $suite);
  182. }
  183. else
  184. {
  185. if ( ! isset(Unittest_tests::$cache[$file]))
  186. {
  187. $relative_path = substr($file, strrpos($file, 'classes'.DIRECTORY_SEPARATOR) + 8, -strlen(EXT));
  188. $cascading_file = Kohana::find_file('classes', $relative_path);
  189. // The theory is that if this file is the highest one in the cascading filesystem
  190. // then it's safe to whitelist
  191. Unittest_tests::$cache[$file] = ($cascading_file === $file);
  192. }
  193. if (Unittest_tests::$cache[$file])
  194. {
  195. if (isset($suite))
  196. {
  197. $suite->addFileToWhitelist($file);
  198. }
  199. else
  200. {
  201. PHPUnit_Util_Filter::addFileToWhitelist($file);
  202. }
  203. }
  204. }
  205. }
  206. }
  207. }