Skip to content

Commit

Permalink
added Haser (hasSomething()) support with unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
esokullu committed May 14, 2017
1 parent f065aa2 commit 966336c
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 10 deletions.
116 changes: 106 additions & 10 deletions src/Pho/Framework/ParticleTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Pho\Framework\Exceptions\InvalidEdgeHeadTypeException;
use Zend\File\ClassFileLocator;
use Pho\Lib\Graph\ID;

/**
* The Particle Trait
Expand Down Expand Up @@ -57,7 +58,7 @@ trait ParticleTrait {
/**
* Getter Labels of Incoming Edges
*
* A simple array of tail labels of incoming edges.
* A simple array of tail labels of incoming edges in plural.
* Tail labels in string format.
*
* @var array
Expand All @@ -67,14 +68,35 @@ trait ParticleTrait {
/**
* Getter Classes of Incoming Edges
*
* An array of tail labels of incoming edges as key
* An array of tail labels of incoming edges in plural as key
* and associated class name as value.
* Both in string format.
*
* @var array
*/
protected $edge_in_getter_classes = [];

/**
* Haser Labels of Incoming Edges
*
* A simple array of tail labels of incoming edges in singular.
* Tail labels in string format.
*
* @var array
*/
protected $edge_in_haser_methods = [];

/**
* Haser Classes of Incoming Edges
*
* An array of tail labels of incoming edges in singular as key
* and associated class name as value.
* Both in string format.
*
* @var array
*/
protected $edge_in_haser_classes = [];

/**
* Setter Labels of Outgoing Edges
*
Expand All @@ -84,6 +106,8 @@ trait ParticleTrait {
*/
protected $edge_out_setter_methods = [];



/**
* Setter Classes of Outgoing Edges
*
Expand All @@ -109,7 +133,7 @@ trait ParticleTrait {
/**
* Getter Labels of Outgoing Edges
*
* A simple array of head labels of outgoing edges.
* A simple array of head labels of outgoing edges in plural.
* Labels in string format.
*
* @var array
Expand All @@ -119,14 +143,35 @@ trait ParticleTrait {
/**
* Getter Classes of Outgoing Edges
*
* An array of head labels of outgoing edges as key,
* An array of head labels of outgoing edges in plural as key,
* associated class names as value.
* Both in string format.
*
* @var array
*/
protected $edge_out_getter_classes = [];

/**
* Haser Labels of Outgoing Edges
*
* A simple array of head labels of outgoing edges in singular.
* Labels in string format.
*
* @var array
*/
protected $edge_out_haser_methods = [];

/**
* Haser Classes of Outgoing Edges
*
* An array of head labels of outgoing edges in singular as key,
* associated class names as value.
* Both in string format.
*
* @var array
*/
protected $edge_out_haser_classes = [];

/**
* Access Control List object
*
Expand Down Expand Up @@ -165,6 +210,9 @@ protected function _setupEdgesIn(): void
$method = $edge_in_class_reflector->getConstant("TAIL_LABELS");
$this->edge_in_getter_methods[] = $method;
$this->edge_in_getter_classes[$method] = $edge_in_class;
$method = $edge_in_class_reflector->getConstant("TAIL_LABEL");
$this->edge_in_haser_methods[] = $method;
$this->edge_in_haser_classes[$method] = $edge_in_class;
}
}
}
Expand Down Expand Up @@ -201,6 +249,10 @@ protected function _setupEdgesOut(): void
$_method = $reflector->getConstant("HEAD_LABELS");
$this->edge_out_getter_methods[] = $_method;
$this->edge_out_getter_classes[$_method] = $class;
$_method = $reflector->getConstant("HEAD_LABEL");
$this->edge_out_haser_methods[] = $_method;
$this->edge_out_haser_classes[$_method] = $class;

}
}
}
Expand All @@ -218,12 +270,16 @@ public function __call(string $name, array $args) {
if(in_array($name, $this->edge_out_setter_methods)) {
return $this->_callSetter($name, $args);
}
else if( (strlen($name) > 3 && substr($name, 0, 3) == "get" ) ) {
try {
return $this->_callGetter($name, $args);
}
catch(InvalidParticleMethodException $e) {
throw $e;
else if(strlen($name) > 3) {
$func_prefix = substr($name, 0, 3);
$funcs = ["get"=>"_callGetter", "has"=>"_callHaser"];
if ( array_key_exists($func_prefix, $funcs) ) {
try {
return $this->{$funcs[$func_prefix]}($name, $args);
}
catch(Exceptions\InvalidParticleMethodException $e) {
throw $e;
}
}
}
throw new Exceptions\InvalidParticleMethodException(__CLASS__, $name);
Expand Down Expand Up @@ -282,6 +338,46 @@ protected function _callGetter(string $name, array $args): array
throw new Exceptions\InvalidParticleMethodException(__CLASS__, $name);
}


/**
* Catch-all method for hasers -hasSomething()-
*
* @param string $name Catch-all method name
* @param array $args Catch-all method arguments. Must contain a single ID for the queried object, or it will throw an exception.
*
* @return bool whether the node exists or not
*
* @throws InvalidArgumentException when the method is called without a single ID object as argument.
* @throws Exceptions\InvalidParticleMethodException when no matching method found.
*/
protected function _callHaser(string $name, array $args): bool
{
if( !isset($args[0]) || !$args[0] instanceof ID ) {
throw new \InvalidArgumentException(
sprintf('The function %s must be called with a single argument that is strictly a \Pho\Lib\Graph\ID object', $name)
);
}
$id = $args[0];
$name = strtolower(substr($name, 3));
if(in_array($name, $this->edge_out_haser_methods)) {
$edges_out = $this->edges()->out();
foreach($edges_out as $edge) {
if($edge instanceof $this->edge_out_haser_classes[$name] && $edge->headID()->equals($id))
return true;
}
return false;
}
else if(in_array($name, $this->edge_in_haser_methods)) {
$edges_in = $this->edges()->in();
foreach($edges_in as $edge) {
if($edge instanceof $this->edge_in_haser_classes[$name] && $edge->tailID()->equals($id))
return true;
}
return false;
}
throw new Exceptions\InvalidParticleMethodException(__CLASS__, $name);
}

/**
* Converts the particle into array
*
Expand Down
10 changes: 10 additions & 0 deletions tests/Pho/Framework/SimpleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ public function testObjectGetter() {
$this->assertInstanceOf(Object::class, $actor->getWrites()[0]);
}

public function testObjectHaser() {
$actor = new Actor($this->graph);
$object = new Object($actor, $this->graph);
$edge = $actor->writes($object);
$this->assertTrue($object->hasWriter($actor->id()));
$this->assertTrue($actor->hasWrite($object->id()));
$this->assertFalse($actor->hasWrite($this->graph->id()));
$this->assertFalse($actor->hasWrite($actor->id()));
}

public function testFiltering() {
$actor = new Actor($this->graph);
$object = new Object($actor, $this->graph);
Expand Down

0 comments on commit 966336c

Please sign in to comment.