Tests.php 4.9 KB

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