PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/run.php

http://github.com/ci-bonfire/Bonfire
PHP | 501 lines | 239 code | 84 blank | 178 comment | 53 complexity | 2ec3f3260f3cf42cacd1e6c025b8726b MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * Please note this file shouldn't be exposed on a live server,
  4. * there is no filtering of $_POST!!!!
  5. */
  6. //--------------------------------------------------------------------
  7. // User Configurable Options
  8. //--------------------------------------------------------------------
  9. // System Folder Paths
  10. //
  11. // Customize these paths if you are using a folder layout other than
  12. // what is provided by default with Bonfire.
  13. $folder = realpath(dirname(__FILE__)).'/';
  14. define('MAIN_PATH', str_replace('tests/', '', $folder));
  15. define('SIMPLETEST', MAIN_PATH .'tests/simpletest/'); // Directory of simpletest
  16. define('ROOT', MAIN_PATH .'public/'); // Directory of codeigniter index.php
  17. define('TESTS_DIR', MAIN_PATH . 'tests/'); // Directory of your tests.
  18. define('APP_DIR', MAIN_PATH . 'application/'); // CodeIgniter Application directory
  19. define('BF_DIR', MAIN_PATH .'bonfire/'); // Bonfire core directory
  20. // Ignore Folders
  21. //
  22. // This array contains names of folders, relative to the
  23. // base 'tests' folder that will be ignored when doing a scan
  24. // the folders to locate tests.
  25. //
  26. // This can be modified at runtime with to include/exclude app-specific
  27. // or Bonfire core folders with the --app_only or -bf_only options on the CLI
  28. $ignore_folders = array(
  29. TESTS_DIR .'support',
  30. TESTS_DIR .'simpletest'
  31. );
  32. // Only Folder
  33. //
  34. // Will only have a value if the -d or --dir flags were used on the CLI
  35. $only_folder = NULL;
  36. // Only File
  37. //
  38. // Will only have a value if the -f or --file flags were used on the CLI
  39. $only_file = isset($_POST['test']) && !empty($_POST['test']) ? $_POST['test'] : null;
  40. //--------------------------------------------------------------------
  41. // END User Configurable Values
  42. //--------------------------------------------------------------------
  43. // Do not edit below this line unless you know what you are doing.
  44. //
  45. //do not use autorun as it output ugly report upon no test run
  46. require_once SIMPLETEST . 'unit_tester.php';
  47. require_once SIMPLETEST . 'mock_objects.php';
  48. require_once SIMPLETEST . 'collector.php';
  49. require_once SIMPLETEST . 'web_tester.php';
  50. require_once TESTS_DIR . '_support/my_reporter.php';
  51. // Bypass any CSRF protection in order to avoid
  52. // modifying simpletest
  53. //
  54. if (isset($_SERVER["REQUEST_METHOD"]) && $_SERVER["REQUEST_METHOD"] == "POST" && isset($_COOKIE['ci_csrf_token']))
  55. {
  56. $_POST['ci_csrf_token'] = $_COOKIE['ci_csrf_token'];
  57. }
  58. //Capture CodeIgniter output, discard and load system into $ci variable
  59. ob_start();
  60. include(ROOT . 'index.php');
  61. $ci =& get_instance();
  62. ob_end_clean();
  63. //--------------------------------------------------------------------
  64. // TEST CLASSES
  65. //--------------------------------------------------------------------
  66. // These classes provide CodeIgniter & Bonfire-specific setup needed
  67. // to use SimpleTest with the project.
  68. //
  69. /**
  70. * CI_UnitTestCase
  71. *
  72. * Provides an parent class our tests can run from. This class extends
  73. * from the default SimpleTest UnitTestCase file. It provides access
  74. * to the $this object in a CI-style manner, as well as additional
  75. * assertions:
  76. *
  77. * - assertEmpty()
  78. * - assertNotEmpty()
  79. */
  80. class CI_UnitTestCase extends UnitTestCase {
  81. protected $ci;
  82. //--------------------------------------------------------------------
  83. public function __construct()
  84. {
  85. parent::__construct();
  86. $this->ci =& get_instance();
  87. }
  88. //--------------------------------------------------------------------
  89. /**
  90. * Allows us to transparently use CI-standard $this->load, etc.
  91. * in our tests and still have them function correctly in the
  92. * test files.
  93. *
  94. * @return mixed
  95. *
  96. * @access public
  97. */
  98. public function __get($var)
  99. {
  100. return $this->ci->$var;
  101. }
  102. //--------------------------------------------------------------------
  103. /**
  104. * Will be true if the value is empty.
  105. *
  106. * @param mixed $value Supposedly empty value.
  107. * @param string $message Message to display.
  108. *
  109. * @return boolean True on pass.
  110. *
  111. * @access public
  112. */
  113. public function assertEmpty($value, $message = '%s')
  114. {
  115. $dumper = new SimpleDumper();
  116. $message = sprintf($message, '[' . $dumper->describeValue($value) . '] should be empty');
  117. return $this->assertTrue(empty($value), $message);
  118. }
  119. //--------------------------------------------------------------------
  120. /**
  121. * Will be true if the value is not empty.
  122. *
  123. * @param mixed $value Supposedly not empty value.
  124. * @param string $message Message to display.
  125. *
  126. * @return boolean True on pass.
  127. *
  128. * @access public
  129. */
  130. public function assertNotEmpty($value, $message = '%s')
  131. {
  132. $dumper = new SimpleDumper();
  133. $message = sprintf($message, '[' . $dumper->describeValue($value) . '] should not be empty');
  134. return $this->assertFalse(empty($value), $message);
  135. }
  136. //--------------------------------------------------------------------
  137. } // end CI_UnitTestCase
  138. //--------------------------------------------------------------------
  139. /**
  140. * CI_WebTestCase
  141. *
  142. * Inherits from the SimpleTest WebTestCase class to provide a simple
  143. * means of accessing the CI $this object when running tests against the
  144. * Web pages themselves.
  145. */
  146. class CI_WebTestCase extends WebTestCase {
  147. protected $ci;
  148. //--------------------------------------------------------------------
  149. public function __construct()
  150. {
  151. parent::WebTestCase();
  152. $this->ci =& get_instance();
  153. }
  154. //--------------------------------------------------------------------
  155. public function __get($var)
  156. {
  157. return $this->ci->$var;
  158. }
  159. //--------------------------------------------------------------------
  160. } // end CI_WebTestCase
  161. //--------------------------------------------------------------------
  162. // END TEST CLASSES
  163. //--------------------------------------------------------------------
  164. //--------------------------------------------------------------------
  165. // UTILITY FUNCTIONS
  166. //--------------------------------------------------------------------
  167. /**
  168. * Function to determine if in cli mode and if so set up variables to make it work
  169. *
  170. * @param Array of commandline args
  171. * @return Boolean true or false if commandline mode setup
  172. *
  173. */
  174. function setup_cli($argv)
  175. {
  176. if (php_sapi_name() == 'cli')
  177. {
  178. if(isset($argv[1]))
  179. {
  180. if(stripos($argv[1],'.php') !== false)
  181. {
  182. $_POST['test'] = $argv[1];
  183. }
  184. else
  185. {
  186. $_POST[$argv[1]] = $argv[1];
  187. }
  188. }
  189. else
  190. {
  191. $_POST['all'] = 'all';
  192. }
  193. $_SERVER['HTTP_HOST'] = '';
  194. $_SERVER['REQUEST_URI'] = '';
  195. return true;
  196. }
  197. return false;
  198. }
  199. //--------------------------------------------------------------------
  200. /**
  201. * Function to map tests and strip .html files.
  202. *
  203. * @param string
  204. * @return array
  205. */
  206. function map_tests($location = '')
  207. {
  208. if (empty($location))
  209. {
  210. return FALSE;
  211. }
  212. $files = directory_map($location);
  213. $return = array();
  214. foreach ($files as $file)
  215. {
  216. if ($file != 'index.html')
  217. {
  218. $return[] = $file;
  219. }
  220. }
  221. return $return;
  222. }
  223. //--------------------------------------------------------------------
  224. /**
  225. * A simple copy of CI's memory_usage method that we use to
  226. * provide a quick overview of memory usage. This is mainly to ensure that
  227. * none of the scripts are getting out of hand.
  228. *
  229. * @return strign The amount of memory used
  230. */
  231. function memory_usage()
  232. {
  233. $size = memory_get_usage(true);
  234. $unit=array('B','KB','MB','GB','TB','PB');
  235. return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
  236. }
  237. //--------------------------------------------------------------------
  238. /**
  239. * discover_tests
  240. *
  241. * Given a base folder, it will recursively scan a folder to
  242. * determine which files are valid test files. Valid test files
  243. * must have either 'Test' or '_test' in their name.
  244. *
  245. * @param string $start_folder The folder to start scanning. If empty, it will
  246. * be the base of the tests folder.
  247. * @param boolean $ignore_onlys If TRUE, will ignore checks for $only_file and $only_folder
  248. * Primarily used for recursive scans.
  249. * @return array The list of test files.
  250. */
  251. function discover_tests($start_folder=null, $ignore_onlys=false)
  252. {
  253. global $ignore_folders, $only_file, $only_folder;
  254. $files = array();
  255. // If no start folder exists, we'll
  256. // set it manually to our tests root
  257. if (is_null($start_folder))
  258. {
  259. $start_folder = TESTS_DIR;
  260. }
  261. // If this is one of the ignore folders
  262. // simply return an empty array.
  263. if (in_array($start_folder, $ignore_folders))
  264. {
  265. return array();
  266. }
  267. $start_folder = rtrim($start_folder, '/');
  268. // Are we restricting to a single file?
  269. if ($only_file && !$ignore_onlys)
  270. {
  271. if (is_file($start_folder .'/'. $only_file))
  272. {
  273. $files[] = $start_folder .'/'. $only_file;
  274. return $files;
  275. }
  276. }
  277. if (!function_exists('directory_map'))
  278. {
  279. global $ci;
  280. $ci->load->helper('directory');
  281. }
  282. $folders = directory_map($start_folder, 1);
  283. // Look through all of our folders & files for
  284. // valid test files.
  285. if (is_array($folders))
  286. {
  287. foreach ($folders as $folder)
  288. {
  289. // remove trailing backslash
  290. $folder = rtrim($folder, DIRECTORY_SEPARATOR);
  291. // Folders get ran back through this function
  292. // and will return an array of valid files.
  293. // Merge this array with ours and call it good.
  294. if (is_dir($start_folder .'/'. $folder) && !in_array($start_folder .'/'. $folder, $ignore_folders))
  295. {
  296. $f = discover_tests($start_folder .'/'. $folder, true);
  297. $files = array_merge($files, $f);
  298. }
  299. else if (is_file($start_folder .'/'. $folder))
  300. {
  301. // Does it appear to be a valid filename?
  302. if (strpos($folder, 'Test') OR strpos($folder, '_test'))
  303. {
  304. $files[] = $start_folder .'/'. $folder;
  305. }
  306. }
  307. }
  308. }
  309. return $files;
  310. }
  311. //--------------------------------------------------------------------
  312. // END UTILITY FUNCTIONS
  313. //--------------------------------------------------------------------
  314. // Make sure we have plenty of time to run the tests.
  315. error_reporting(E_ALL ^ E_NOTICE);
  316. // Are we running in cli mode?
  317. $is_cli = setup_cli($argv);
  318. if ($is_cli)
  319. {
  320. // Setup our allowed short/long options
  321. $short_opts = '';
  322. $short_opts .= 'a'; // Include the applications folder tests only. Not Bonfire core.
  323. $short_opts .= 'b'; // Include Bonfire's core tests only, not the app-specific ones.
  324. $short_opts .= 'f:'; // Restrict to a single file
  325. $short_opts .= 'd:'; // Restrict to a single folder
  326. $long_opts = array(
  327. 'app_only', // Include the applications folder tests only. Not Bonfire core.
  328. 'bf_only', // Include Bonfire's core tests only, not the app-specific ones.
  329. 'file:', // Restrict to a single file
  330. 'dir:', // Restrict to a single folder
  331. );
  332. $cli_opts = getopt($short_opts, $long_opts);
  333. // If we are on an app_only or bf_only run,
  334. // then add the folders to the ignored folders
  335. if (array_key_exists('a', $cli_opts) || array_key_exists('app_only', $cli_opts))
  336. {
  337. $ignore_folders[] = str_replace('src', 'tests', BF_DIR);
  338. }
  339. else if (array_key_exists('b', $cli_opts) || array_key_exists('bf_only', $cli_opts))
  340. {
  341. $ignore_folders[] = str_replace('src', 'tests', APP_DIR);
  342. }
  343. else if (array_key_exists('f', $cli_opts) || array_key_exists('file', $cli_opts) )
  344. {
  345. $only_file = array_key_exists('file', $cli_opts) ? $cli_opts['file'] : $cli_opts['f'];
  346. }
  347. else if (array_key_exists('d', $cli_opts) || array_key_exists('dir', $cli_opts) )
  348. {
  349. $only_folder = array_key_exists('dir', $cli_opts) ? $cli_opts['dir'] : $cli_opts['d'];
  350. }
  351. }
  352. // Setup similar options via $_GET vars for the GUI version
  353. else
  354. {
  355. if (isset($_GET['a']) || isset($_GET['app_only']) || isset($_POST['app_only']))
  356. {
  357. $ignore_folders[] = rtrim( str_replace('src', 'tests', BF_DIR), '/');
  358. }
  359. else if (isset($_GET['b']) || isset($_GET['bf_only']) || isset($_POST['bf_only']))
  360. {
  361. $ignore_folders[] = rtrim(str_replace('src', 'tests', APP_DIR), '/');
  362. }
  363. else if (isset($_GET['f']) || isset($_GET['file']))
  364. {
  365. $only_file = isset($_GET['f']) ? $_GET['f'] : $_GET['file'];
  366. }
  367. else if (isset($_GET['d']) || isset($_GET['dir']))
  368. {
  369. $only_folder = isset($_GET['d']) ? $_GET['d'] : $_GET['dir'];
  370. }
  371. }
  372. $test_suite = new TestSuite();
  373. $test_suite->_label = 'Bonfire Test Suite';
  374. // We destroy the session here so that tests can create
  375. // their own sessions. This also allows us to not contaminate test
  376. // results with our own session information.
  377. $ci->load->library('session');
  378. $ci->session->sess_destroy();
  379. $ci->load->helper('directory');
  380. // Start your engines!
  381. $test_start = microtime();
  382. $test_files = null;
  383. // TODO Revise to allow args from the CLI as folder/file names
  384. $only_folder = isset($only_folder) && !empty($only_folder) ? TESTS_DIR . $only_folder : null;
  385. $all_tests = discover_tests(TESTS_DIR, true);
  386. $test_files = discover_tests($only_folder);
  387. // Add the found test files to the suite to be tested.
  388. if (is_array($test_files))
  389. {
  390. foreach ($test_files as $file)
  391. {
  392. $test_suite->addFile($file);
  393. }
  394. }
  395. // ------------------------------------------------------------------------
  396. //variables for report
  397. /*
  398. $controllers = map_tests(TESTS_DIR . 'controllers');
  399. $models = map_tests(TESTS_DIR . 'models');
  400. $views = map_tests(TESTS_DIR . 'views');
  401. $libraries = map_tests(TESTS_DIR . 'libraries');
  402. $bugs = map_tests(TESTS_DIR . 'bugs');
  403. $helpers = map_tests(TESTS_DIR . 'helpers');
  404. */
  405. $form_url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  406. $test_end = microtime();
  407. /* Benchmark */
  408. list($sm, $ss) = explode(' ', $test_start);
  409. list($em, $es) = explode(' ', $test_end);
  410. $elapse_time = number_format(($em + $es) - ($sm + $ss), 4);
  411. //display the form
  412. if ($is_cli) {
  413. exit ($test_suite->run(new TextReporter()) ? 0 : 1);
  414. }
  415. else {
  416. include(TESTS_DIR . 'test_gui.php');
  417. }