Skip to content
Snippets Groups Projects
Commit 04252c05 authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Added root namespace functionality to autoloader.

parent ba02966d
No related branches found
No related tags found
No related merge requests found
<?php
/**
*
* A tool for autoloading PHP classes within a root directory and namespace.
*
* @author Taddeus Kroes
* @version 1.0
......@@ -65,12 +65,11 @@ class Autoloader extends Base {
/**
* The namespace classes in the root directory are expected to be in.
*
* This namespace is removed from loaded class names.
* This namespace is removed from the beginning of loaded class names.
*
* @var string
* @todo implement this
*/
private $root_namespace = '';
private $root_namespace = '\\';
/**
* Whether to throw an exception when a class file does not exist.
......@@ -85,7 +84,7 @@ class Autoloader extends Base {
* @param string $directory Root directory of the autoloader.
* @param bool $throw Whether to throw an exception when a class file does not exist.
*/
function __construct($directory, $throw=true) {
function __construct($directory, $throw=false) {
$this->set_root_directory($directory);
$this->set_throw_errors($throw);
}
......@@ -126,6 +125,28 @@ class Autoloader extends Base {
return $this->root_directory;
}
/**
* Set the root namespace that loaded classes are expected to be in.
*
* @param string $directory The new root namespace.
*/
function set_root_namespace($namespace) {
// Assert that the namespace ends with a backslash
if( $namespace[strlen($namespace) - 1] != '\\' )
$namespace .= '\\';
$this->root_namespace = $namespace;
}
/**
* Get the root namespace that loaded classes are expected to be in.
*
* @return string
*/
function get_root_namespace() {
return $this->root_namespace;
}
/**
* Append a slash ('/') to the given directory name, if it is not already there.
*
......@@ -149,6 +170,21 @@ class Autoloader extends Base {
return strtolower(preg_replace('/(?<=.)([A-Z])/', '_\\1', $classname));
}
/**
* Strip the root namespace from the beginning of a class name.
*
* @param string $classname The name of the class to strip the namespace from.
* @return string The stripped class name.
*/
private function strip_root_namespace($classname) {
$begin = substr($classname, 0, strlen($this->root_namespace));
if( $begin == $this->root_namespace )
$classname = substr($classname, strlen($this->root_namespace));
return $classname;
}
/**
* Create the path to a class file.
*
......@@ -180,14 +216,15 @@ class Autoloader extends Base {
* @return bool
* @throws FileNotFoundError If the class file does not exist.
*/
function load_class($classname, $throw=true) {
function load_class($classname, $throw=null) {
$classname = $this->strip_root_namespace($classname);
$path = $this->create_path($classname);
if( !file_exists($path) ) {
if( !$throw || !$this->throw_errors )
return false;
if( $throw || ($throw === null && $this->throw_errors) )
throw new FileNotFoundError($path);
throw new FileNotFoundError($path);
return false;
}
require_once $path;
......
......@@ -10,6 +10,34 @@ class AutoloaderTest extends PHPUnit_Framework_TestCase {
$this->autoloader = new Autoloader(PATH);
}
function test_set_root_namespace() {
$this->assertAttributeEquals('\\', 'root_namespace', $this->autoloader);
$this->autoloader->set_root_namespace('Foo');
$this->assertAttributeEquals('Foo\\', 'root_namespace', $this->autoloader);
$this->autoloader->set_root_namespace('Foo\\');
$this->assertAttributeEquals('Foo\\', 'root_namespace', $this->autoloader);
}
/**
* @depends test_set_root_namespace
*/
function test_get_root_namespace() {
$this->autoloader->set_root_namespace('Foo');
$this->assertEquals($this->autoloader->get_root_namespace(), 'Foo\\');
}
/**
* @depends test_set_root_namespace
*/
function test_strip_root_namespace() {
$strip = new ReflectionMethod('BasicWeb\Autoloader', 'strip_root_namespace');
$strip->setAccessible(true);
$this->autoloader->set_root_namespace('Foo');
$this->assertEquals($strip->invoke($this->autoloader, 'Foo\Bar'), 'Bar');
}
function test_path_with_slash() {
$this->assertEquals(Autoloader::path_with_slash('dirname'), 'dirname/');
$this->assertEquals(Autoloader::path_with_slash('dirname/'), 'dirname/');
......@@ -41,15 +69,47 @@ class AutoloaderTest extends PHPUnit_Framework_TestCase {
$this->assertEquals($this->autoloader->create_path('FooBar\Baz'), PATH.'foo_bar/baz.php');
}
function test_throw_errors() {
$this->assertFalse($this->autoloader->get_throw_errors());
$this->autoloader->set_throw_errors(true);
$this->assertTrue($this->autoloader->get_throw_errors());
}
/**
* @depends test_create_path
* @depends test_throw_errors
*/
function test_load_class_not_found() {
$this->assertFalse($this->autoloader->load_class('foobar'));
}
/**
* @depends test_load_class_not_found
* @expectedException BasicWeb\FileNotFoundError
* @expectedExceptionMessage File "tests/_files/foobar.php" does not exist.
*/
function test_load_class_not_found() {
function test_load_class_not_found_error() {
$this->autoloader->set_throw_errors(true);
$this->autoloader->load_class('foobar');
}
/**
* @depends test_load_class_not_found
* @expectedException BasicWeb\FileNotFoundError
* @expectedExceptionMessage File "tests/_files/foobar.php" does not exist.
*/
function test_load_class_not_found_noerror_overwrite() {
$this->autoloader->load_class('foobar', true);
}
/**
* @depends test_load_class_not_found
*/
function test_load_class_not_found_error_overwrite() {
$this->autoloader->set_throw_errors(true);
$this->assertFalse($this->autoloader->load_class('foobar', false));
}
/**
* @depends test_load_class_not_found
*/
......@@ -60,6 +120,17 @@ class AutoloaderTest extends PHPUnit_Framework_TestCase {
$this->assertTrue(class_exists('Foo\Bar', false));
}
/**
* @depends test_load_class
* @depends test_strip_root_namespace
*/
function test_load_class_root_namespace() {
$autoloader = new Autoloader(PATH.'foo');
$autoloader->set_root_namespace('Foo');
$this->assertTrue($autoloader->load_class('Bar'));
$this->assertTrue(class_exists('Foo\Bar', false));
}
/**
* @depends test_load_class
*/
......@@ -68,12 +139,6 @@ class AutoloaderTest extends PHPUnit_Framework_TestCase {
$this->assertTrue(class_exists('Baz'));
}
function test_throw_errors() {
$this->assertTrue($this->autoloader->get_throw_errors());
$this->autoloader->set_throw_errors(false);
$this->assertFalse($this->autoloader->get_throw_errors());
}
/**
* @depends test_register
* @depends test_throw_errors
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment