blob: e5c86322c02a063e662d242efa4dc2fc21f41809 [file] [log] [blame]
Pascal Kriete69c97a72011-04-20 21:44:54 -04001<?php
2
Pascal Krietefe372e32011-04-21 00:59:45 -04003class CI_TestCase extends PHPUnit_Framework_TestCase {
Andrey Andreevf243ce12012-06-09 23:34:21 +03004
dchill427ecc5cd2012-10-12 16:25:51 -04005 public $ci_vfs_root;
6 public $ci_app_root;
7 public $ci_base_root;
Pascal Krieteae7b3f92011-04-21 01:21:27 -04008 protected $ci_instance;
9 protected static $ci_test_instance;
Andrey Andreevf243ce12012-06-09 23:34:21 +030010
Pascal Krieteae7b3f92011-04-21 01:21:27 -040011 private $global_map = array(
Pascal Kriete69c97a72011-04-20 21:44:54 -040012 'benchmark' => 'bm',
13 'config' => 'cfg',
14 'hooks' => 'ext',
15 'utf8' => 'uni',
16 'router' => 'rtr',
17 'output' => 'out',
18 'security' => 'sec',
19 'input' => 'in',
20 'lang' => 'lang',
Greg Aker8da69032011-04-21 11:28:27 -050021 'loader' => 'load',
22 'model' => 'model'
Pascal Kriete69c97a72011-04-20 21:44:54 -040023 );
Andrey Andreevf243ce12012-06-09 23:34:21 +030024
Eric Barnes68286a42011-04-21 22:00:33 -040025 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +030026
Pascal Krietefe372e32011-04-21 00:59:45 -040027 public function __construct()
Pascal Kriete69c97a72011-04-20 21:44:54 -040028 {
29 parent::__construct();
Abdul Malik Ikhsana8b29ac2013-04-01 01:14:39 +070030 $this->ci_instance = new stdClass();
Pascal Kriete69c97a72011-04-20 21:44:54 -040031 }
Andrey Andreevf243ce12012-06-09 23:34:21 +030032
Pascal Kriete69c97a72011-04-20 21:44:54 -040033 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +030034
Eric Barnes68286a42011-04-21 22:00:33 -040035 public function setUp()
36 {
dchill427ecc5cd2012-10-12 16:25:51 -040037 // Setup VFS with base directories
38 $this->ci_vfs_root = vfsStream::setup();
39 $this->ci_app_root = vfsStream::newDirectory('application')->at($this->ci_vfs_root);
40 $this->ci_base_root = vfsStream::newDirectory('system')->at($this->ci_vfs_root);
dchill424f42be52012-10-21 21:31:19 -040041 $this->ci_view_root = vfsStream::newDirectory('views')->at($this->ci_app_root);
dchill427ecc5cd2012-10-12 16:25:51 -040042
Eric Barnes68286a42011-04-21 22:00:33 -040043 if (method_exists($this, 'set_up'))
44 {
45 $this->set_up();
46 }
47 }
Andrey Andreevf243ce12012-06-09 23:34:21 +030048
Eric Barnes68286a42011-04-21 22:00:33 -040049 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +030050
51 public function tearDown()
Eric Barnes68286a42011-04-21 22:00:33 -040052 {
53 if (method_exists($this, 'tear_down'))
54 {
55 $this->tear_down();
56 }
57 }
Taufan Adityae1dc9ea2012-03-28 16:49:49 +070058
59 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +030060
Taufan Adityae1dc9ea2012-03-28 16:49:49 +070061 public static function instance()
62 {
63 return self::$ci_test_instance;
64 }
Andrey Andreevf243ce12012-06-09 23:34:21 +030065
Eric Barnes68286a42011-04-21 22:00:33 -040066 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +030067
dchill427ecc5cd2012-10-12 16:25:51 -040068 public function ci_set_config($key = '', $val = '')
Pascal Kriete69c97a72011-04-20 21:44:54 -040069 {
dchill427ecc5cd2012-10-12 16:25:51 -040070 // Add test config
71 if ( ! isset($this->ci_instance->config))
72 {
73 $this->ci_instance->config = new CI_TestConfig();
74 }
75
76 // Empty key means just do setup above
77 if ($key === '')
78 {
79 return;
80 }
81
Pascal Krieteae7b3f92011-04-21 01:21:27 -040082 if (is_array($key))
83 {
dchill427ecc5cd2012-10-12 16:25:51 -040084 $this->ci_instance->config->config = $key;
Pascal Krieteae7b3f92011-04-21 01:21:27 -040085 }
86 else
87 {
dchill427ecc5cd2012-10-12 16:25:51 -040088 $this->ci_instance->config->config[$key] = $val;
Pascal Krieteae7b3f92011-04-21 01:21:27 -040089 }
Pascal Krietefe372e32011-04-21 00:59:45 -040090 }
Taufan Adityae1dc9ea2012-03-28 16:49:49 +070091
92 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +030093
94 public function ci_get_config()
Taufan Adityae1dc9ea2012-03-28 16:49:49 +070095 {
dchill427ecc5cd2012-10-12 16:25:51 -040096 return isset($this->ci_instance->config) ? $this->ci_instance->config->config : array();
Taufan Adityae1dc9ea2012-03-28 16:49:49 +070097 }
Andrey Andreevf243ce12012-06-09 23:34:21 +030098
Pascal Krietefe372e32011-04-21 00:59:45 -040099 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +0300100
101 public function ci_instance($obj = FALSE)
Pascal Krietefe372e32011-04-21 00:59:45 -0400102 {
103 if ( ! is_object($obj))
104 {
105 return $this->ci_instance;
106 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300107
Pascal Kriete69c97a72011-04-20 21:44:54 -0400108 $this->ci_instance = $obj;
109 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300110
Pascal Kriete69c97a72011-04-20 21:44:54 -0400111 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +0300112
113 public function ci_instance_var($name, $obj = FALSE)
Pascal Kriete69c97a72011-04-20 21:44:54 -0400114 {
Pascal Krietefe372e32011-04-21 00:59:45 -0400115 if ( ! is_object($obj))
116 {
117 return $this->ci_instance->$name;
118 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300119
Pascal Kriete69c97a72011-04-20 21:44:54 -0400120 $this->ci_instance->$name =& $obj;
121 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300122
Pascal Kriete69c97a72011-04-20 21:44:54 -0400123 // --------------------------------------------------------------------
Pascal Kriete69c97a72011-04-20 21:44:54 -0400124
125 /**
126 * Grab a core class
127 *
128 * Loads the correct core class without extensions
129 * and returns a reference to the class name in the
130 * globals array with the correct key. This way the
131 * test can modify the variable it assigns to and
132 * still maintain the global.
133 */
Andrey Andreevf243ce12012-06-09 23:34:21 +0300134 public function &ci_core_class($name)
Pascal Kriete69c97a72011-04-20 21:44:54 -0400135 {
136 $name = strtolower($name);
Andrey Andreevf243ce12012-06-09 23:34:21 +0300137
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400138 if (isset($this->global_map[$name]))
Pascal Kriete69c97a72011-04-20 21:44:54 -0400139 {
140 $class_name = ucfirst($name);
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400141 $global_name = $this->global_map[$name];
Pascal Kriete69c97a72011-04-20 21:44:54 -0400142 }
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400143 elseif (in_array($name, $this->global_map))
Pascal Kriete69c97a72011-04-20 21:44:54 -0400144 {
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400145 $class_name = ucfirst(array_search($name, $this->global_map));
Pascal Kriete69c97a72011-04-20 21:44:54 -0400146 $global_name = $name;
147 }
148 else
149 {
150 throw new Exception('Not a valid core class.');
151 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300152
Pascal Kriete69c97a72011-04-20 21:44:54 -0400153 if ( ! class_exists('CI_'.$class_name))
154 {
dchill427ecc5cd2012-10-12 16:25:51 -0400155 require_once SYSTEM_PATH.'core/'.$class_name.'.php';
Pascal Kriete69c97a72011-04-20 21:44:54 -0400156 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300157
Pascal Kriete69c97a72011-04-20 21:44:54 -0400158 $GLOBALS[strtoupper($global_name)] = 'CI_'.$class_name;
159 return $GLOBALS[strtoupper($global_name)];
160 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300161
Pascal Kriete69c97a72011-04-20 21:44:54 -0400162 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +0300163
Pascal Kriete69c97a72011-04-20 21:44:54 -0400164 // convenience function for global mocks
Andrey Andreevf243ce12012-06-09 23:34:21 +0300165 public function ci_set_core_class($name, $obj)
Pascal Kriete69c97a72011-04-20 21:44:54 -0400166 {
167 $orig =& $this->ci_core_class($name);
168 $orig = $obj;
169 }
Andrey Andreevf243ce12012-06-09 23:34:21 +0300170
dchill427ecc5cd2012-10-12 16:25:51 -0400171 /**
172 * Create VFS directory
173 *
174 * @param string Directory name
175 * @param object Optional root to create in
176 * @return object New directory object
177 */
178 public function ci_vfs_mkdir($name, $root = NULL)
179 {
180 // Check for root
181 if ( ! $root)
182 {
183 $root = $this->ci_vfs_root;
184 }
185
186 // Return new directory object
187 return vfsStream::newDirectory($name)->at($root);
188 }
189
190 // --------------------------------------------------------------------
191
192 /**
193 * Create VFS content
194 *
195 * @param string File name
196 * @param string File content
197 * @param object VFS directory object
198 * @param mixed Optional subdirectory path or array of subs
199 * @return void
200 */
201 public function ci_vfs_create($file, $content = '', $root = NULL, $path = NULL)
202 {
203 // Check for array
204 if (is_array($file))
205 {
206 foreach ($file as $name => $content)
207 {
208 $this->ci_vfs_create($name, $content, $root, $path);
209 }
210 return;
211 }
212
213 // Assert .php extension if none given
214 if (pathinfo($file, PATHINFO_EXTENSION) == '')
215 {
216 $file .= '.php';
217 }
218
219 // Build content
220 $tree = array($file => $content);
221
222 // Check for path
223 $subs = array();
224 if ($path)
225 {
226 // Explode if not array
227 $subs = is_array($path) ? $path : explode('/', trim($path, '/'));
228 }
229
230 // Check for root
231 if ( ! $root)
232 {
233 // Use base VFS root
234 $root = $this->ci_vfs_root;
235 }
236
237 // Handle subdirectories
238 while (($dir = array_shift($subs)))
239 {
240 // See if subdir exists under current root
241 $dir_root = $root->getChild($dir);
242 if ($dir_root)
243 {
244 // Yes - recurse into subdir
245 $root = $dir_root;
246 }
247 else
248 {
249 // No - put subdirectory back and quit
250 array_unshift($subs, $dir);
251 break;
252 }
253 }
254
255 // Create any remaining subdirectories
256 if ($subs)
257 {
258 foreach (array_reverse($subs) as $dir)
259 {
260 // Wrap content in subdirectory for creation
261 $tree = array($dir => $tree);
262 }
263 }
264
265 // Create tree
266 vfsStream::create($tree, $root);
267 }
268
269 // --------------------------------------------------------------------
270
271 /**
272 * Clone a real file into VFS
273 *
274 * @param string Path from base directory
275 * @return bool TRUE on success, otherwise FALSE
276 */
Dan Bernardic168ba6c2015-01-10 21:11:01 -0600277 public function ci_vfs_clone($path, $dest='')
dchill427ecc5cd2012-10-12 16:25:51 -0400278 {
dchill42e9435dc2012-10-14 15:44:39 -0400279 // Check for array
280 if (is_array($path))
281 {
282 foreach ($path as $file)
283 {
Dan Bernardic168ba6c2015-01-10 21:11:01 -0600284 $this->ci_vfs_clone($file, $dest);
dchill42e9435dc2012-10-14 15:44:39 -0400285 }
286 return;
287 }
288
dchill427ecc5cd2012-10-12 16:25:51 -0400289 // Get real file contents
290 $content = file_get_contents(PROJECT_BASE.$path);
291 if ($content === FALSE)
292 {
293 // Couldn't find file to clone
294 return FALSE;
295 }
296
Dan Bernardic168ba6c2015-01-10 21:11:01 -0600297 if (empty($dest))
298 {
299 $dest = dirname($path);
300 }
301
302 $this->ci_vfs_create(basename($path), $content, NULL, $dest);
dchill427ecc5cd2012-10-12 16:25:51 -0400303 return TRUE;
304 }
305
306 // --------------------------------------------------------------------
307
308 /**
309 * Helper to get a VFS URL path
310 *
311 * @param string Path
312 * @param string Optional base path
313 * @return string Path URL
314 */
315 public function ci_vfs_path($path, $base = '')
316 {
317 // Check for base path
318 if ($base)
319 {
320 // Prepend to path
321 $path = rtrim($base, '/').'/'.ltrim($path, '/');
322
323 // Is it already in URL form?
324 if (strpos($path, '://') !== FALSE)
325 {
326 // Done - return path
327 return $path;
328 }
329 }
330
331 // Trim leading slash and return URL
332 return vfsStream::url(ltrim($path, '/'));
333 }
334
Pascal Kriete69c97a72011-04-20 21:44:54 -0400335 // --------------------------------------------------------------------
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400336 // Internals
337 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +0300338
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400339 /**
340 * Overwrite runBare
341 *
342 * PHPUnit instantiates the test classes before
343 * running them individually. So right before a test
344 * runs we set our instance. Normally this step would
345 * happen in setUp, but someone is bound to forget to
346 * call the parent method and debugging this is no fun.
347 */
348 public function runBare()
Pascal Krietefe372e32011-04-21 00:59:45 -0400349 {
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400350 self::$ci_test_instance = $this;
351 parent::runBare();
Pascal Krietefe372e32011-04-21 00:59:45 -0400352 }
Taufan Adityae1dc9ea2012-03-28 16:49:49 +0700353
Pascal Krietefe372e32011-04-21 00:59:45 -0400354 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +0300355
356 public function helper($name)
Pascal Krieteae7b3f92011-04-21 01:21:27 -0400357 {
dchill427ecc5cd2012-10-12 16:25:51 -0400358 require_once(SYSTEM_PATH.'helpers/'.$name.'_helper.php');
359 }
360
361 // --------------------------------------------------------------------
362
363 public function lang($name)
364 {
365 require(SYSTEM_PATH.'language/english/'.$name.'_lang.php');
366 return $lang;
Pascal Krietefe372e32011-04-21 00:59:45 -0400367 }
Taufan Aditya8749bc72012-03-11 05:43:45 +0700368
369 // --------------------------------------------------------------------
Andrey Andreevf243ce12012-06-09 23:34:21 +0300370
Taufan Aditya8749bc72012-03-11 05:43:45 +0700371 /**
372 * This overload is useful to create a stub, that need to have a specific method.
373 */
Andrey Andreevf243ce12012-06-09 23:34:21 +0300374 public function __call($method, $args)
Taufan Aditya8749bc72012-03-11 05:43:45 +0700375 {
Andrey Andreevf243ce12012-06-09 23:34:21 +0300376 if ($this->{$method} instanceof Closure)
Taufan Aditya8749bc72012-03-11 05:43:45 +0700377 {
378 return call_user_func_array($this->{$method},$args);
Andrey Andreevf243ce12012-06-09 23:34:21 +0300379 }
Andrey Andreevfbe4d792017-12-27 19:49:03 +0200380
381 return parent::__call($method, $args);
Taufan Aditya8749bc72012-03-11 05:43:45 +0700382 }
Pascal Kriete69c97a72011-04-20 21:44:54 -0400383
Dan Bernardic168ba6c2015-01-10 21:11:01 -0600384}