Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Loader unit test improvements

Signed-off-by: dchill42 <dchill42@gmail.com>
  • Loading branch information...
commit c8f39ebf6c43a3bf4722896d3d8ae4ff101904b8 1 parent 16dce4d
@dchill42 authored
View
69 system/core/Loader.php
@@ -1119,23 +1119,24 @@ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
}
}
- // We'll test for both lowercase and capitalized versions of the file name
+ // Is this a class extension request?
$pre = $this->CI->config->item('subclass_prefix');
- foreach (array(ucfirst($class), strtolower($class)) as $class)
+ foreach ($this->_ci_library_paths as $path)
{
- $file = 'libraries/'.$subdir.$pre.$class.'.php';
- foreach ($this->_ci_library_paths as $path)
+ // Try both upper- and lower-class in path subdirectory
+ $path .= 'libraries/'.$subdir;
+ foreach (array(ucfirst($class), strtolower($class)) as $class)
{
- // Is this a class extension request?
- $subclass = $path.$file;
+ $subclass = $path.$pre.$class.'.php';
if (file_exists($subclass))
{
- // Found extension - require base class
+ // Found extension - require base class (in base path, no subdir, always capital)
$baseclass = $this->_ci_base_path.'libraries/'.ucfirst($class).'.php';
if ( ! file_exists($baseclass))
{
- log_message('error', 'Unable to load the requested class: '.$class);
- show_error('Unable to load the requested class: '.$class);
+ $msg = 'Unable to load the requested class: '.$class;
+ log_message('error', $msg);
+ show_error($msg);
}
// Safety: Was the class already loaded by a previous call?
@@ -1144,15 +1145,11 @@ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
// Before we deem this to be a duplicate request, let's see
// if a custom object name is being supplied. If so, we'll
// return a new instance of the object
- if ( ! is_null($object_name))
+ if ( ! is_null($object_name) && ! isset($this->CI->$object_name))
{
- if ( ! isset($this->CI->$object_name))
- {
- return $this->_ci_init_class($class, $pre, $params, $object_name);
- }
+ return $this->_ci_init_class($class, $pre, $params, $object_name);
}
- $is_duplicate = TRUE;
log_message('debug', $class.' class already loaded. Second attempt ignored.');
return;
}
@@ -1164,35 +1161,34 @@ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
return $this->_ci_init_class($class, $pre, $params, $object_name);
}
- }
+ }
+ }
- // Lets search for the requested library file and load it.
- $is_duplicate = FALSE;
- foreach ($this->_ci_library_paths as $path)
+ // Let's search for the requested library file and load it.
+ foreach ($this->_ci_library_paths as $path)
+ {
+ // Try both upper- and lower-class in path subdirectory
+ $path .= 'libraries/'.$subdir;
+ foreach (array(ucfirst($class), strtolower($class)) as $class)
{
- $filepath = $path.'libraries/'.$subdir.$class.'.php';
-
// Does the file exist? No? Bummer...
- if ( ! file_exists($filepath))
+ $file = $path.$class.'.php';
+ if ( ! file_exists($file))
{
continue;
}
// Safety: Was the class already loaded by a previous call?
- if (in_array($filepath, $this->_ci_loaded_files))
+ if (in_array($file, $this->_ci_loaded_files))
{
// Before we deem this to be a duplicate request, let's see
// if a custom object name is being supplied. If so, we'll
// return a new instance of the object
- if ( ! is_null($object_name))
+ if ( ! is_null($object_name) && ! isset($this->CI->$object_name))
{
- if ( ! isset($this->CI->$object_name))
- {
- return $this->_ci_init_class($class, '', $params, $object_name);
- }
+ return $this->_ci_init_class($class, '', $params, $object_name);
}
- $is_duplicate = TRUE;
log_message('debug', $class.' class already loaded. Second attempt ignored.');
return;
}
@@ -1204,11 +1200,11 @@ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
require $this->_ci_base_path.'libraries/Driver.php';
}
- include_once($filepath);
- $this->_ci_loaded_files[] = $filepath;
+ include_once($file);
+ $this->_ci_loaded_files[] = $file;
return $this->_ci_init_class($class, '', $params, $object_name);
}
- } // END FOREACH
+ }
// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
if ($subdir === '')
@@ -1224,12 +1220,9 @@ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
}
// If we got this far we were unable to find the requested class.
- // We do not issue errors if the load call failed due to a duplicate request
- if ($is_duplicate === FALSE)
- {
- log_message('error', 'Unable to load the requested class: '.$class);
- show_error('Unable to load the requested class: '.$class);
- }
+ $msg = 'Unable to load the requested class: '.$class;
+ log_message('error', $msg);
+ show_error($msg);
}
// --------------------------------------------------------------------
View
200 tests/codeigniter/core/Loader_test.php
@@ -6,25 +6,22 @@ class Loader_test extends CI_TestCase {
public function set_up()
{
- // Create VFS tree of loader locations
- $this->root = vfsStream::setup();
- $this->base_root = vfsStream::newDirectory('system')->at($this->root);
- $this->app_root = vfsStream::newDirectory('application')->at($this->root);
- $this->view_root = vfsStream::newDirectory('views')->at($this->root);
+ // Create VFS tree
+ $this->ci_vfs_setup();
- // Get VFS path URLs
- $this->base_path = vfsStream::url('system').'/';
- $this->app_path = vfsStream::url('application').'/';
- $this->view_path = vfsStream::url('views').'/';
+ // Add view path to VFS
+ $this->ci_view_root = vfsStream::newDirectory('views')->at($this->ci_vfs_root);
+ $this->ci_view_path = vfsStream::url('views/');
// Set up config
- $this->ci_set_config('subclass_prefix', 'MY_');
+ $this->subclass = 'MY_';
+ $this->ci_set_config('subclass_prefix', $this->subclass);
// Get CI instance and set empty autoload.php contents and path sources
$this->ci_obj = $this->ci_instance();
$this->ci_obj->_autoload = array();
- $this->ci_obj->base_paths = array($this->app_path, $this->base_path);
- $this->ci_obj->app_paths = array($this->app_path);
+ $this->ci_obj->base_paths = array($this->ci_app_path, $this->ci_base_path);
+ $this->ci_obj->app_paths = array($this->ci_app_path);
// Instantiate a new loader
$this->load = new Mock_Core_Loader();
@@ -40,7 +37,7 @@ public function test_library()
// Create libraries directory with test library
$lib = 'unit_test_lib';
$class = 'CI_'.ucfirst($lib);
- $this->_create_content('libraries', $lib, '<?php class '.$class.' { } ', NULL, TRUE);
+ $this->ci_vfs_create($lib, $this->_empty($class), $this->ci_base_root, 'libraries');
// Test loading as an array.
$this->assertNull($this->load->library(array($lib)));
@@ -61,13 +58,14 @@ public function test_library()
*/
public function test_library_config()
{
- // Create libraries directory with test library
- $lib = 'unit_test_config_lib';
- $class = 'CI_'.ucfirst($lib);
+ // Create libraries directory with capitalized test library in subdir
+ $sub = 'mylibs';
+ $lib = ucfirst('unit_test_config_lib');
+ $class = 'CI_'.$lib;
$content = '<?php class '.$class.
' { public function __construct($params = NULL) { $this->config = $params; } } ';
- $this->_create_content('libraries', $lib, $content, NULL, TRUE);
-
+ $this->ci_vfs_create($lib, $content, $this->ci_base_root, 'libraries', $sub);
+
// Create config to be loaded
// For isolation, we just set the contents in CI_TestConfig to be retrieved
$cfg = array(
@@ -75,13 +73,19 @@ public function test_library_config()
'bar' => 'baz',
'baz' => false
);
- $this->ci_obj->config->to_get = $cfg;
-
- // Test object name and config
+ $this->ci_obj->config->to_get($cfg);
+
+ // Load library with object name
$obj = 'testy';
- $this->assertNull($this->load->library($lib, NULL, $obj));
+ $this->assertNull($this->load->library($sub.'/'.$lib, NULL, $obj));
+
+ // Was the class instantiated?
$this->assertTrue(class_exists($class), $class.' does not exist');
+ $this->assertObjectHasAttribute($obj, $this->ci_obj);
$this->assertAttributeInstanceOf($class, $obj, $this->ci_obj);
+
+ // Did the config get set?
+ $this->assertObjectHasAttribute('config', $this->ci_obj->$obj);
$this->assertEquals($cfg, $this->ci_obj->$obj->config);
}
@@ -95,19 +99,47 @@ public function test_load_library_in_application_dir()
// Create libraries directory in app path with test library
$lib = 'super_test_library';
$class = ucfirst($lib);
- $this->_create_content('libraries', $lib, '<?php class '.$class.' {} ');
+ $this->ci_vfs_create($lib, $this->_empty($class), $this->ci_app_root, 'libraries');
// Load library
$this->assertNull($this->load->library($lib));
- // Was the model class instantiated?
+ // Was the class instantiated?
$this->assertTrue(class_exists($class), $class.' does not exist');
+ $this->assertObjectHasAttribute($lib, $this->ci_obj);
$this->assertAttributeInstanceOf($class, $lib, $this->ci_obj);
}
// --------------------------------------------------------------------
/**
+ * @covers CI_Loader::library
+ */
+ public function test_library_subclass()
+ {
+ // Create libraries directory in base path with test library
+ $lib = 'sub_test_library';
+ $class = ucfirst($lib);
+ $this->ci_vfs_create($class, $this->_empty($class), $this->ci_base_root, 'libraries');
+
+ // Create library subclass in app path libraries directory
+ $content = '<?php class '.$this->subclass.$class.' extends '.$class.' { } ';
+ $this->ci_vfs_create($this->subclass.$lib, $content, $this->ci_app_root, 'libraries');
+
+ // Load library
+ $this->assertNull($this->load->library($lib));
+
+ // Was the class instantiated?
+ $this->assertTrue(class_exists($class), $class.' does not exist');
+ $this->assertTrue(class_exists($this->subclass.$class), $this->subclass.$class.' does not exist');
+ $this->assertObjectHasAttribute($lib, $this->ci_obj);
+ $this->assertAttributeInstanceOf($class, $lib, $this->ci_obj);
+ $this->assertAttributeInstanceOf($this->subclass.$class, $lib, $this->ci_obj);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* @covers CI_Loader::driver
*/
public function test_driver()
@@ -116,21 +148,23 @@ public function test_driver()
$driver = 'unit_test_driver';
$dir = ucfirst($driver);
$class = 'CI_'.$dir;
- $this->_create_content('libraries', $driver, '<?php class '.$class.' { } ', $dir, TRUE);
-
+ $this->ci_vfs_create($driver, $this->_empty($class), $this->ci_base_root, 'libraries', $dir);
+
// Test loading as an array.
$this->assertNull($this->load->driver(array($driver)));
$this->assertTrue(class_exists($class), $class.' does not exist');
+ $this->assertObjectHasAttribute($driver, $this->ci_obj);
$this->assertAttributeInstanceOf($class, $driver, $this->ci_obj);
-
+
// Test loading as a library with a name
$obj = 'testdrive';
$this->assertNull($this->load->library($driver, NULL, $obj));
+ $this->assertObjectHasAttribute($obj, $this->ci_obj);
$this->assertAttributeInstanceOf($class, $obj, $this->ci_obj);
-
+
// Test no driver given
$this->assertFalse($this->load->driver());
-
+
// Test a string given to params
$this->assertNull($this->load->driver($driver, ' '));
}
@@ -142,12 +176,13 @@ public function test_driver()
*/
public function test_non_existent_model()
{
+ $model = 'ci_test_nonexistent_model.php';
+
$this->setExpectedException(
'RuntimeException',
- 'CI Error: Unable to locate the model you have specified: ci_test_nonexistent_model.php'
+ 'CI Error: Unable to locate the model you have specified: '.$model
);
-
- $this->load->model('ci_test_nonexistent_model.php');
+ $this->load->model($model);
}
// --------------------------------------------------------------------
@@ -157,18 +192,20 @@ public function test_non_existent_model()
*/
public function test_models()
{
- $this->ci_set_core_class('model', 'CI_Model');
-
// Create models directory with test model
$model = 'unit_test_model';
+ $base = 'CI_Model';
$class = ucfirst($model);
- $this->_create_content('models', $model, '<?php class '.$class.' extends CI_Model {} ');
+ $this->ci_vfs_create($model, '<?php class '.$class.' extends '.$base.' {} ', $this->ci_app_root, 'models');
// Load model
$this->assertNull($this->load->model($model));
- // Was the model class instantiated.
+ // Was the model class instantiated?
$this->assertTrue(class_exists($class));
+ $this->assertObjectHasAttribute($model, $this->ci_obj);
+ $this->assertAttributeInstanceOf($base, $model, $this->ci_obj);
+ $this->assertAttributeInstanceOf($class, $model, $this->ci_obj);
// Test no model given
$this->assertNull($this->load->model(''));
@@ -189,15 +226,13 @@ public function test_models()
*/
public function test_load_view()
{
- $this->ci_set_core_class('output', 'CI_Output');
-
// Create views directory with test view
$view = 'unit_test_view';
- $this->_create_content('views', $view, 'This is my test page. <?php echo $hello; ?>');
+ $this->ci_vfs_create($view, 'This is my test page. <?php echo $hello; ?>', $this->ci_app_root, 'views');
// Use the optional return parameter in this test, so the view is not
// run through the output class.
- $out = $this->load->view($view, array('hello' => "World!"), TRUE);
+ $out = $this->load->view($view, array('hello' => 'World!'), TRUE);
$this->assertEquals('This is my test page. World!', $out);
}
@@ -208,12 +243,14 @@ public function test_load_view()
*/
public function test_non_existent_view()
{
+ $view = 'ci_test_nonexistent_view';
+
$this->setExpectedException(
'RuntimeException',
- 'CI Error: Unable to load the requested file: ci_test_nonexistent_view.php'
+ 'CI Error: Unable to load the requested file: '.$view.'.php'
);
- $this->load->view('ci_test_nonexistent_view', array('foo' => 'bar'));
+ $this->load->view($view, array('foo' => 'bar'));
}
// --------------------------------------------------------------------
@@ -227,10 +264,10 @@ public function test_file()
$dir = 'views';
$file = 'ci_test_mock_file';
$content = 'Here is a test file, which we will load now.';
- $this->_create_content($dir, $file, $content);
+ $this->ci_vfs_create($file, $content, $this->ci_app_root, $dir);
// Just like load->view(), take the output class out of the mix here.
- $out = $this->load->file($this->app_path.$dir.'/'.$file.'.php', TRUE);
+ $out = $this->load->file($this->ci_app_path.$dir.'/'.$file.'.php', TRUE);
$this->assertEquals($content, $out);
// Test non-existent file
@@ -263,12 +300,13 @@ public function test_helper()
// Create helper directory in app path with test helper
$helper = 'test';
$func = '_my_helper_test_func';
- $this->_create_content('helpers', $helper.'_helper', '<?php function '.$func.'() { return true; } ');
-
+ $content = '<?php function '.$func.'() { return true; } ';
+ $this->ci_vfs_create($helper.'_helper', $content, $this->ci_app_root, 'helpers');
+
// Load helper
$this->assertNull($this->load->helper($helper));
$this->assertTrue(function_exists($func), $func.' does not exist');
-
+
// Test non-existent helper
$this->setExpectedException(
'RuntimeException',
@@ -296,11 +334,11 @@ public function test_loading_multiple_helpers()
$funcs[] = $func;
$files[$helper.'_helper'] = '<?php function '.$func.'() { return true; } ';
}
- $this->_create_content('helpers', $files, NULL, NULL, TRUE);
-
+ $this->ci_vfs_create($files, NULL, $this->ci_base_root, 'helpers');
+
// Load helpers
$this->assertEquals(NULL, $this->load->helpers($helpers));
-
+
// Verify helper existence
foreach ($funcs as $func) {
$this->assertTrue(function_exists($func), $func.' does not exist');
@@ -327,25 +365,25 @@ public function test_packages()
$dir = 'third-party';
$lib = 'unit_test_package';
$class = 'CI_'.ucfirst($lib);
- $this->_create_content($dir, $lib, '<?php class '.$class.' { } ');
-
+ $this->ci_vfs_create($lib, $this->_empty($class), $this->ci_app_root, $dir);
+
// Test failed load without path
$this->setExpectedException('RuntimeException', 'CI Error: Unable to load the requested class: '.$lib);
$this->load->library($lib);
-
+
// Clear exception and get paths
$this->setExpectedException(NULL);
$paths = $this->load->get_package_paths(TRUE);
-
+
// Add path and verify
- $path = $this->app_path.$dir;
+ $path = $this->ci_app_path.$dir;
$this->assertNull($this->load->add_package_path($path));
$this->assertContains($path, $this->load->get_package_paths(TRUE));
-
+
// Test successful load
$this->assertNull($this->load->library($lib));
$this->assertTrue(class_exists($class), $class.' does not exist');
-
+
// Remove path and verify restored paths
$this->assertNull($this->load->remove_package_path($path));
$this->assertEquals($paths, $this->load->get_package_paths(TRUE));
@@ -371,30 +409,27 @@ public function test_autoloader()
// Create helper directory in app path with test helper
$helper = 'autohelp';
$hlp_func = '_autohelp_test_func';
- $this->_create_content('helpers', $helper.'_helper', '<?php function '.$hlp_func.'() { return true; } ');
+ $content = '<?php function '.$hlp_func.'() { return true; } ';
+ $this->ci_vfs_create($helper.'_helper', $content, $this->ci_app_root, 'helpers');
// Create libraries directory in base path with test library
$lib = 'autolib';
$lib_class = 'CI_'.ucfirst($lib);
- $this->_create_content('libraries', $lib, '<?php class '.$lib_class.' { } ', NULL, TRUE);
+ $this->ci_vfs_create($lib, $this->_empty($lib_class), $this->ci_base_root, 'libraries');
// Create libraries subdirectory with test driver
- // Since libraries/ now exists, we have to look it up and
- // add the subdir directly instead of using _create_content
$drv = 'autodrv';
$subdir = ucfirst($drv);
$drv_class = 'CI_'.$subdir;
- $tree = array(
- $subdir => array($drv.'.php' => '<?php class '.$drv_class.' { } ')
- );
- vfsStream::create($tree, $this->base_root->getChild('libraries'));
+ $this->ci_vfs_create($drv, $this->_empty($drv_class), $this->ci_base_root, 'libraries', $subdir);
// Create package directory in app path with model
$dir = 'testdir';
- $path = $this->app_path.$dir.'/';
+ $path = $this->ci_app_path.$dir.'/';
$model = 'automod';
$mod_class = ucfirst($model);
- $this->_create_content($dir, $model, '<?php class '.$mod_class.' { } ', 'models');
+ $this->ci_vfs_create($model, $this->_empty($mod_class), $this->ci_app_root, $dir, 'models');
+ $this->ci_vfs_create($model, $this->_empty($mod_class), $this->ci_app_root, $dir, 'models');
// Autoload path since autoloaded packages are handled during bootstrapping
$this->load->add_package_path($path);
@@ -432,36 +467,9 @@ public function test_autoloader()
// --------------------------------------------------------------------
- private function _create_content($dir, $file, $content, $sub = NULL, $base = FALSE)
+ private function _empty($class)
{
- // Create structure containing directory
- $tree = array($dir => array());
-
- // Check for subdirectory
- if ($sub) {
- // Add subdirectory to tree and get reference
- $tree[$dir][$sub] = array();
- $leaf =& $tree[$dir][$sub];
- }
- else {
- // Get reference to main directory
- $leaf =& $tree[$dir];
- }
-
- // Check for multiple files
- if (is_array($file)) {
- // Add multiple files to directory
- foreach ($file as $name => $data) {
- $leaf[$name.'.php'] = $data;
- }
- }
- else {
- // Add single file with content
- $leaf[$file.'.php'] = $content;
- }
-
- // Create structure under app or base path
- vfsStream::create($tree, $base ? $this->base_root : $this->app_root);
+ return '<?php class '.$class.' { } ';
}
}
View
10 tests/mocks/ci_testcase.php
@@ -198,6 +198,16 @@ public function ci_vfs_setup()
*/
public function ci_vfs_create($file, $content, $root = NULL, $dir = NULL, $sub = NULL)
{
+ // Check for array
+ if (is_array($file))
+ {
+ foreach ($file as $name => $content)
+ {
+ $this->ci_vfs_create($name, $content, $root, $dir, $sub);
+ }
+ return;
+ }
+
// Assert .php extension
if (strrpos($file, '.php') !== strlen($file) - 4)
{
View
5 tests/mocks/ci_testconfig.php
@@ -19,5 +19,10 @@ public function get($arg1, $arg2)
{
return $this->to_get;
}
+
+ public function to_get($config)
+ {
+ $this->to_get = $config;
+ }
}
View
6 tests/mocks/core/loader.php
@@ -17,9 +17,9 @@ public function __construct()
{
// Get VFS paths from test case
$test = CI_TestCase::instance();
- $this->_ci_base_path = $test->base_path;
- $this->_ci_app_path = $test->app_path;
- $this->_ci_view_path = $test->view_path;
+ $this->_ci_base_path = $test->ci_base_path;
+ $this->_ci_app_path = $test->ci_app_path;
+ $this->_ci_view_path = $test->ci_view_path;
// Run parent constructor
parent::__construct();
Please sign in to comment.
Something went wrong with that request. Please try again.