1<?php 2/** 3 * Helper class to provide basic functionality for tests 4 */ 5abstract class DokuWikiTest extends PHPUnit_Framework_TestCase { 6 7 /** 8 * tests can override this 9 * 10 * @var array plugins to enable for test class 11 */ 12 protected $pluginsEnabled = array(); 13 14 /** 15 * tests can override this 16 * 17 * @var array plugins to disable for test class 18 */ 19 protected $pluginsDisabled = array(); 20 21 /** 22 * Setup the data directory 23 * 24 * This is ran before each test class 25 */ 26 public static function setUpBeforeClass() { 27 // just to be safe not to delete something undefined later 28 if(!defined('TMP_DIR')) die('no temporary directory'); 29 if(!defined('DOKU_TMP_DATA')) die('no temporary data directory'); 30 31 // remove any leftovers from the last run 32 if(is_dir(DOKU_TMP_DATA)){ 33 // clear indexer data and cache 34 idx_get_indexer()->clear(); 35 TestUtils::rdelete(DOKU_TMP_DATA); 36 } 37 38 // populate default dirs 39 TestUtils::rcopy(TMP_DIR, dirname(__FILE__).'/../data/'); 40 } 41 42 /** 43 * Reset the DokuWiki environment before each test run. Makes sure loaded config, 44 * language and plugins are correct. 45 * 46 * @throws Exception if plugin actions fail 47 * @return void 48 */ 49 public function setUp() { 50 51 // reload config 52 global $conf, $config_cascade; 53 $conf = array(); 54 foreach (array('default','local','protected') as $config_group) { 55 if (empty($config_cascade['main'][$config_group])) continue; 56 foreach ($config_cascade['main'][$config_group] as $config_file) { 57 if (file_exists($config_file)) { 58 include($config_file); 59 } 60 } 61 } 62 63 // reload license config 64 global $license; 65 $license = array(); 66 67 // load the license file(s) 68 foreach (array('default','local') as $config_group) { 69 if (empty($config_cascade['license'][$config_group])) continue; 70 foreach ($config_cascade['license'][$config_group] as $config_file) { 71 if(file_exists($config_file)){ 72 include($config_file); 73 } 74 } 75 } 76 // reload some settings 77 $conf['gzip_output'] &= (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false); 78 79 if($conf['compression'] == 'bz2' && !DOKU_HAS_BZIP) { 80 $conf['compression'] = 'gz'; 81 } 82 if($conf['compression'] == 'gz' && !DOKU_HAS_GZIP) { 83 $conf['compression'] = 0; 84 } 85 // make real paths and check them 86 init_paths(); 87 init_files(); 88 89 // reset loaded plugins 90 global $plugin_controller_class, $plugin_controller; 91 /** @var Doku_Plugin_Controller $plugin_controller */ 92 $plugin_controller = new $plugin_controller_class(); 93 94 // disable all non-default plugins 95 global $default_plugins; 96 foreach ($plugin_controller->getList() as $plugin) { 97 if (!in_array($plugin, $default_plugins)) { 98 if (!$plugin_controller->disable($plugin)) { 99 throw new Exception('Could not disable plugin "'.$plugin.'"!'); 100 } 101 } 102 } 103 104 // disable and enable configured plugins 105 foreach ($this->pluginsDisabled as $plugin) { 106 if (!$plugin_controller->disable($plugin)) { 107 throw new Exception('Could not disable plugin "'.$plugin.'"!'); 108 } 109 } 110 foreach ($this->pluginsEnabled as $plugin) { 111 /* enable() returns false but works... 112 if (!$plugin_controller->enable($plugin)) { 113 throw new Exception('Could not enable plugin "'.$plugin.'"!'); 114 } 115 */ 116 $plugin_controller->enable($plugin); 117 } 118 119 // reset event handler 120 global $EVENT_HANDLER; 121 $EVENT_HANDLER = new Doku_Event_Handler(); 122 123 // reload language 124 $local = $conf['lang']; 125 trigger_event('INIT_LANG_LOAD', $local, 'init_lang', true); 126 127 global $INPUT; 128 $INPUT = new Input(); 129 } 130 131 /** 132 * Compatibility for older PHPUnit versions 133 * 134 * @param string $originalClassName 135 * @return PHPUnit_Framework_MockObject_MockObject 136 */ 137 protected function createMock($originalClassName) { 138 if(is_callable(array('parent', 'createMock'))) { 139 return parent::createMock($originalClassName); 140 } else { 141 return $this->getMock($originalClassName); 142 } 143 } 144 145 /** 146 * Compatibility for older PHPUnit versions 147 * 148 * @param string $originalClassName 149 * @param array $methods 150 * @return PHPUnit_Framework_MockObject_MockObject 151 */ 152 protected function createPartialMock($originalClassName, array $methods) { 153 if(is_callable(array('parent', 'createPartialMock'))) { 154 return parent::createPartialMock($originalClassName, $methods); 155 } else { 156 return $this->getMock($originalClassName, $methods); 157 } 158 } 159 160 /** 161 * Waits until a new second has passed 162 * 163 * The very first call will return immeadiately, proceeding calls will return 164 * only after at least 1 second after the last call has passed. 165 * 166 * When passing $init=true it will not return immeadiately but use the current 167 * second as initialization. It might still return faster than a second. 168 * 169 * @param bool $init wait from now on, not from last time 170 * @return int new timestamp 171 */ 172 protected function waitForTick($init = false) { 173 static $last = 0; 174 if($init) $last = time(); 175 while($last === $now = time()) { 176 usleep(100000); //recheck in a 10th of a second 177 } 178 $last = $now; 179 return $now; 180 } 181} 182