Joey Mazzarelli avatar Joey Mazzarelli committed 0abb2f0

new autoloader and some working tests

Comments (0)

Files changed (15)

src/php/Trekel.php

   public function closest ($selector) {
   }
 
+  static public function autoload ($class) {
+    if ('Trekel_' == substr($class, 0, 7)) {
+      $file = str_replace('_', DIRECTORY_SEPARATOR, $class) . ".php";
+      @include_once $file;
+    }
+  }
+
 } // end Trekel
 
+spl_autoload_register(array('Trekel', 'autoload'));
+
+

src/php/Trekel/Evaluator.php

     do {
       $staging = new Trekel_List();
       foreach ($matches as $match) {
-        foreach ($node->reduce($match) as $item) {
-          $staging->append($item);
-        }
+        $staging->appendAll($node->reduce($match));
       }
       $matches = $staging;
     } while (null !== ($node = $node->getChild()));

src/php/Trekel/List.php

 <?php
 
-class Trekel_List implements IteratorAggregate {
+class Trekel_List extends Trekel_Set implements IteratorAggregate {
 
-  private $list = null;
-  private $set = null;
+  private $list = array();
+  private $idx = 0;
 
-  public function __construct () {
-    $this->set = new Trekel_Set();
-    $this->list = array();
+  public function append ($node) {
+    if ($node && !$this->has($node)) {
+      $this->add($node);
+      $this->list[] = $node;
+    }
   }
 
-  public function append ($node) {
-    if (!$this->set->has($node)) {
-      $this->set->add($node);
-      $this->list[] = $node;
+  public function appendAll ($nodes) {
+    foreach ($nodes as $node) {
+      $this->append($node);
     }
   }
 
     return $this->list;
   }
 
+  public function next () {
+    if (isset($this->list[$this->idx])) {
+      return $this->list[$this->idx++];
+    }
+    return null;
+  }
+
 } // end Trekel_List

src/php/Trekel/Node.php

   }
 
   protected function getChildren ($node) {
-    return array();
+    if (!$node) {
+      return array();
+    }
+    return array($node->getChild());
   }
 
   protected function getParent ($node) {
+    return $node->getParent();
+  }
+
+
+  private $queue;
+
+  protected function initQueue ($node) {
+    $this->queue = new Trekel_List();
+    $this->queue->append($node);
+  }
+
+  protected function enqueue ($node) {
+    if (is_array($node)) {
+      $this->queue->appendAll($node);
+    } else {
+      $this->queue->append($node);
+    }
+  }
+
+  protected function dequeue () {
+    return $this->queue->next();
   }
 
 } // end Trekel_Node

src/php/Trekel/Node/Pseudo.php

     $type = ucfirst($type);
     $class = "Trekel_Node_Pseudo_{$type}";
     if (!class_exists($class)) {
-      $file = str_replace('_', '/', $class) . ".php";
-      @include_once $file;
-      if (!class_exists($class)) {
-        return null;
-      }
+      return null;
+    } else {
+      return new $class($data);
     }
-    return new $class($data);
   }
 
 } // end Trekel_Node_Pseudo

src/php/Trekel/Node/Selector.php

 <?php
 
-require_once 'Trekel/Node.php';
-
 abstract class Trekel_Node_Selector extends Trekel_Node {
 
   public function coerce ($type) {

src/php/Trekel/Node/Selector/Child.php

 <?php
 
 class Trekel_Node_Selector_Child extends Trekel_Node_Selector {
-  public function reduce ($node) { return array(); }
+
+  public function reduce ($node) {
+    $this->initMatches();
+    $this->matchType($node);
+    return $this->getMatches();
+  }
+
 }

src/php/Trekel/Node/Selector/Descendant.php

 
   public function reduce ($node) {
     $this->initMatches();
-    $queue = array($node);
-    while (count($queue)) {
-      $node = array_shift($queue);
+    $this->initQueue($node);
+    while ($node = $this->dequeue()) {
       $this->matchType($node);
-      $queue = array_merge($queue, $this->getChildren($node));
+      $this->enqueue($this->getChildren($node));
     }
     return $this->getMatches();
   }
 
-}
+} // Trekel_Node_Selector_Descendant

src/php/Trekel/Set.php

 <?php
 
-class Trekel_Set {
+class Trekel_Set implements IteratorAggregate, Countable {
 
   private $set = array();
-  private $prefix;
+  private $salt;
 
   public function __construct () {
-    $this->prefix = spl_object_hash($this);
+    $this->salt = __CLASS__ . spl_object_hash($this);
   }
 
   public function has ($item) {
   }
 
   public function add ($item) {
-    $this->set[$this->id($item)] = true;
+    $this->set[$this->id($item)] = $item;
   }
 
   public function remove ($item) {
 
   private function id ($item) {
     if (is_scalar($item)) {
-      return "{$this->prefix}{$item}";
-
-    } else if (is_array($item)) {
-      // whatever...
-      return "{$this->prefix}{$item}";
+      return "{$this->salt}{$item}";
 
     } else if (is_object($item)) {
-      return "{$this->prefix}" . spl_object_hash($item);
+      return "{$this->salt}" . spl_object_hash($item);
 
     } else {
-      // seriously, what is this? A resource? I guess I just "try"...
-      return "{$this->prefix}{$item}";
+      throw new Exception("unsupported type");
+
     }
-  } // end id()
+  }
 
-}
+  public function getIterator () {
+    return new ArrayIterator($this->set);
+  }
+
+  public function count () {
+    return count($this->set);
+  }
+
+} // end Trekel_Set

src/phplemon/Trekel/Parser.y

  * official policies, either expressed or implied, of Joey Mazzarelli.
  */
 
-if (!class_exists('Trekel')) {
   require_once 'Trekel.php';
-  require_once 'Trekel/Lexer.php';
-  require_once 'Trekel/List.php';
-  require_once 'Trekel/Node.php';
-  require_once 'Trekel/Node/Attribute.php';
-  require_once 'Trekel/Node/Attribute/Contains.php';
-  require_once 'Trekel/Node/Attribute/EndsWith.php';
-  require_once 'Trekel/Node/Attribute/Equals.php';
-  require_once 'Trekel/Node/Attribute/Exists.php';
-  require_once 'Trekel/Node/Attribute/NotEquals.php';
-  require_once 'Trekel/Node/Attribute/StartsWith.php';
-  require_once 'Trekel/Node/Pseudo.php';
-  require_once 'Trekel/Node/Selector.php';
-  require_once 'Trekel/Node/Selector/Adjacent.php';
-  require_once 'Trekel/Node/Selector/Child.php';
-  require_once 'Trekel/Node/Selector/Descendant.php';
-  require_once 'Trekel/Node/Selector/Sibling.php';
-  require_once 'Trekel/ParseException.php';
-  require_once 'Trekel/Set.php';
-} // end file inclusions
 
 }
 

src/test/php/Trekel/DescendantTest.php

+<?php
+/**
+ * Copyright 2010 Joey Mazzarelli. All rights reserved.
+ *
+ * Redistribution and use in source, with or without modification, is
+ * permitted provided that the following condition is met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Joey Mazzarelli.
+ */
+
+require_once dirname(__FILE__) . '/TestCase.php';
+
+class Trekel_DescendantTest extends Trekel_TestCase {
+
+  public function testSimpleSingle () {
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_A');
+    $parseTree = $parser->parse();
+    $rootNode = new Trekel_DescendantTest_A();
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setParseTree($parseTree);
+    $evaluator->setRootNode($rootNode);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(1, count($nodes));
+  }
+
+  public function testSimpleEmpty () {
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_A');
+    $parseTree = $parser->parse();
+    $rootNode = new Trekel_DescendantTest_B();
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setParseTree($parseTree);
+    $evaluator->setRootNode($rootNode);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(0, count($nodes));
+  }
+
+  public function testSimpleCycle () {
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_A');
+    $parseTree = $parser->parse();
+    $rootNode = new Trekel_DescendantTest_A();
+    // throw in a cycle, test for infinite loops
+    $rootNode->addChild($rootNode);
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setParseTree($parseTree);
+    $evaluator->setRootNode($rootNode);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(1, count($nodes));
+  }
+
+  public function testAnother () {
+    $nodeA = new Trekel_DescendantTest_A();
+    $nodeB = new Trekel_DescendantTest_B();
+    $nodeC = new Trekel_DescendantTest_C();
+    $nodeD = new Trekel_DescendantTest_D();
+    $nodeA->addChild($nodeB);
+    $nodeB->addChild($nodeC);
+    $nodeC->addChild($nodeD);
+
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_Base');
+    $parseTree = $parser->parse();
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setRootNode($nodeA);
+    $evaluator->setParseTree($parseTree);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(4, count($nodes));
+
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_A');
+    $parseTree = $parser->parse();
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setRootNode($nodeA);
+    $evaluator->setParseTree($parseTree);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(1, count($nodes));
+
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_B');
+    $parseTree = $parser->parse();
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setRootNode($nodeA);
+    $evaluator->setParseTree($parseTree);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(1, count($nodes));
+
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_C');
+    $parseTree = $parser->parse();
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setRootNode($nodeA);
+    $evaluator->setParseTree($parseTree);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(2, count($nodes));
+
+    $parser = new Trekel_Parser();
+    $parser->setSelector('Trekel_DescendantTest_D');
+    $parseTree = $parser->parse();
+    $evaluator = new Trekel_Evaluator();
+    $evaluator->setRootNode($nodeA);
+    $evaluator->setParseTree($parseTree);
+    $nodes = $evaluator->evaluate();
+    $this->assertEquals(1, count($nodes));
+  }
+
+
+} // end Trekel_DescendantTest
+
+class Trekel_DescendantTest_Base {
+  private $child;
+  private $parent;
+  public function getChild () {
+    return $this->child;
+  }
+  public function getParent () {
+    return $this->parent;
+  }
+  public function addChild ($child) {
+    $child->setParent($this);
+    $this->child = $child;
+  }
+  public function setParent ($parent) {
+    $this->parent = $parent;
+  }
+}
+class Trekel_DescendantTest_A extends Trekel_DescendantTest_Base { }
+class Trekel_DescendantTest_B extends Trekel_DescendantTest_Base { }
+class Trekel_DescendantTest_C extends Trekel_DescendantTest_Base { }
+class Trekel_DescendantTest_D extends Trekel_DescendantTest_C { }
+class Trekel_DescendantTest_E extends Trekel_DescendantTest_D { }
+

src/test/php/Trekel/EvaluatorTest.php

-<?php
-/**
- * Copyright 2010 Joey Mazzarelli. All rights reserved.
- *
- * Redistribution and use in source, with or without modification, is
- * permitted provided that the following condition is met:
- *
- *    1. Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Joey Mazzarelli.
- */
-
-require_once dirname(__FILE__) . '/TestCase.php';
-require_once 'Trekel/Evaluator.php';
-require_once 'Trekel/Parser.php';
-
-class Trekel_EvaluatorTest extends Trekel_TestCase {
-
-  public function testDescendants () {
-
-    $parser = new Trekel_Parser();
-    $parser->setSelector('A B C');
-    $parseTree = $parser->parse();
-
-    $evaluator = new Trekel_Evaluator();
-    $evaluator->setParseTree($parseTree);
-    $evaluator->setRootNode($parseTree);
-
-    $nodes = $evaluator->evaluate();
-    print_r($nodes);
-
-  }
-
-
-} // end Trekel_EvaluatorTest
-

src/test/php/Trekel/ParserTest.php

  */
 
 require_once dirname(__FILE__) . '/TestCase.php';
-require_once 'Trekel/Parser.php';
 
 class Trekel_ParserTest extends Trekel_TestCase {
 

src/test/php/Trekel/SetTest.php

+<?php
+/**
+ * Copyright 2010 Joey Mazzarelli. All rights reserved.
+ *
+ * Redistribution and use in source, with or without modification, is
+ * permitted provided that the following condition is met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Joey Mazzarelli.
+ */
+
+require_once dirname(__FILE__) . '/TestCase.php';
+
+class Trekel_SetTest extends Trekel_TestCase {
+
+  public function testSet () {
+
+    $set = new Trekel_Set();
+    $this->assertFalse($set->has("foo"));
+    $set->add("foo");
+    $this->assertTrue($set->has("foo"));
+    $this->assertEquals(1, count($set));
+    $set->add("foo");
+    $this->assertEquals(1, count($set));
+    $set->add("bar");
+    $this->assertEquals(2, count($set));
+    $obj = new StdClass;
+    $this->assertFalse($set->has($obj));
+    $set->add($obj);
+    $set->add($obj);
+    $set->add($obj);
+    $set->add($obj);
+    $this->assertTrue($set->has($obj));
+    $this->assertEquals(3, count($set));
+    $set->remove($obj);
+    $this->assertFalse($set->has($obj));
+    $this->assertEquals(2, count($set));
+
+  }
+
+
+} // end Trekel_SetTest
+

src/test/php/Trekel/TestCase.php

                  dirname(__FILE__) . '/../../../php/');
 
 require_once 'PHPUnit/Framework/TestCase.php';
+require_once 'Trekel.php';
 
 class Trekel_TestCase extends PHPUnit_Framework_TestCase { }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.