Introduce a file loader to the UrlMap.
authorRobert Sesek <rsesek@bluestatic.org>
Sat, 6 Aug 2011 22:28:49 +0000 (18:28 -0400)
committerRobert Sesek <rsesek@bluestatic.org>
Sat, 6 Aug 2011 22:34:23 +0000 (18:34 -0400)
http/url_map.php
testing/tests/http/url_map_test.php

index fac6a4260bb0aab122b35dac59521b42d2629a00..ad7541a2389c965b5a5113d26c5ec83639a6fefd 100644 (file)
@@ -31,6 +31,9 @@ class UrlMap
   /*! @var array The map of URLs to actions. */
   private $map = array();
 
+  /*! @var Closure(string) Loads the file for the appropriate action class name. */
+  private $file_loader = NULL;
+
   /*!
     Constructs the object with a reference to the RootController.
     @param RootController
@@ -80,6 +83,15 @@ class UrlMap
   */
   public function set_map(array $map) { $this->map = $map; }
 
+  /*! @brief The file loading helper function.
+    This function is called in ::LookupAction() and will load the necessary file
+    for this class so that it can be instantiated. Should return the class name
+    to instantiate. This can either be the first argument passed to it
+    unaltered, or modified for example with a namespace.
+    Closure(string $class_name, string $map_value) -> string $new_class_name
+  */
+  public function set_file_loader(\Closure $fn) { $this->file_loader = $fn; }
+
   /*! @brief Evalutes the URL map and finds a match.
     This will take the incoming URL from the request and will match it against
     the patterns in the internal map.
@@ -189,18 +201,26 @@ class UrlMap
     // If the first character is uppercase or a namespaced class, simply return
     // the value.
     $first_char = $map_value[0];
-    if ($first_char == '\\' || ctype_upper($first_char))
-      return $map_value;
-
-    // Otherwise this is a path. Check if an extension is present, and if not,
-    // add one.
-    $pathinfo = pathinfo($map_value);
-    if (!isset($pathinfo['extension'])) {
-      $map_value .= '.php';
-      $pathinfo['extension'] = 'php';
+    if ($first_char == '\\' || ctype_upper($first_char)) {
+      $class = $map_value;
+    } else {
+      // Otherwise this is a path. Check if an extension is present, and if not,
+      // add one.
+      $pathinfo = pathinfo($map_value);
+      if (!isset($pathinfo['extension'])) {
+        $map_value .= '.php';
+        $pathinfo['extension'] = 'php';
+      }
+
+      $class = $this->_ClassNameFromFileName($pathinfo);
+    }
+
+    if ($this->file_loader) {
+      $loader = $this->file_loader;
+      $class = $loader($class, $map_value);
     }
 
-    return $this->_ClassNameFromFileName($pathinfo);
+    return new $class($this->controller());
   }
 
   /*!
index 722eb3225d169a05763cf9387b5395be6f6f47c7..72fbaf28e12c62b6a2df3e31c8360fde7b136056 100644 (file)
@@ -19,6 +19,11 @@ use hoplite\http as http;
 
 require_once HOPLITE_ROOT . '/http/url_map.php';
 
+class TestAction extends http\Action
+{
+  public function Invoke(http\Request $request, http\Response $response) {}
+}
+
 class UrlMapTest extends \PHPUnit_Framework_TestCase
 {
   public function setUp()
@@ -171,16 +176,41 @@ class UrlMapTest extends \PHPUnit_Framework_TestCase
 
   public function testLookupActionClass()
   {
+    $self = $this;
+
+    $this->fixture->set_file_loader(function ($name, $value) use ($self) {
+      $self->assertEquals('\hoplite\test\TestAction', $name);
+      $self->assertEquals('\hoplite\test\TestAction', $value);
+      return 'hoplite\test\TestAction';
+    });
     $test_class = '\hoplite\test\TestAction';
-    $this->assertEquals($test_class, $this->fixture->LookupAction($test_class));
+    $this->assertInstanceOf('hoplite\test\TestAction', $this->fixture->LookupAction($test_class));
 
+    $this->fixture->set_file_loader(function ($name, $value) use ($self) {
+      $self->assertEquals('TestAction', $name);
+      $self->assertEquals('TestAction', $value);
+      return 'hoplite\test\TestAction';
+    });
     $test_class = 'TestAction';
-    $this->assertEquals($test_class, $this->fixture->LookupAction($test_class));
+    $this->assertInstanceOf('hoplite\test\TestAction', $this->fixture->LookupAction($test_class));
   }
 
   public function testLookupActionFile()
   {
-    $this->assertEquals('TestAction', $this->fixture->LookupAction('actions/test_action'));
-    $this->assertEquals('TestAction', $this->fixture->LookupAction('actions/test_action.php'));
+    $self = $this;
+
+    $this->fixture->set_file_loader(function ($name, $value) use ($self) {
+      $self->assertEquals('TestAction', $name);
+      $self->assertEquals('actions/test_action.php', $value);
+      return 'hoplite\test\TestAction';
+    });
+    $this->assertInstanceOf('hoplite\test\TestAction', $this->fixture->LookupAction('actions/test_action'));
+
+    $this->fixture->set_file_loader(function ($name, $value) use ($self) {
+      $self->assertEquals('TestAction', $name);
+      $self->assertEquals('actions/test_action.php', $value);
+      return 'hoplite\test\TestAction';
+    });
+    $this->assertInstanceOf('hoplite\test\TestAction', $this->fixture->LookupAction('actions/test_action.php'));
   }
 }