Commit 04252c05 authored by Taddeus Kroes's avatar Taddeus Kroes

Added root namespace functionality to autoloader.

parent ba02966d
<?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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment