Created
March 8, 2013 08:50
-
-
Save gbirke/5115086 to your computer and use it in GitHub Desktop.
This PHPUnit constraint class is for applying another constraint to a value inside a nested array structure.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This constraint class is for applying another constraint to a value inside a nested array structure. | |
* | |
* When initializing this constraint you specify a "key path" - an array of keys, each accessing the next level of the | |
* array to check. | |
* | |
* @author Gabriel Birke <[email protected]> | |
*/ | |
class NestedArrayConstraint extends PHPUnit_Framework_Constraint | |
{ | |
private $path; | |
private $constraint; | |
private $pathMatches = false; | |
private $pathValue; | |
/** | |
* @param array $path Key path to the desired value | |
* @param PHPUnit_Framework_Constraint $constraint Constraint that will be evaluated with the value at the end of the key path | |
*/ | |
public function __construct($path, PHPUnit_Framework_Constraint $constraint){ | |
$this->path = $path; | |
$this->constraint = $constraint; | |
} | |
/** | |
* Check if the array contains the keys in $this->path and if it does, delegate evaluation to internal constraint | |
* | |
* @param mixed $other | |
* @param string $description | |
* @param bool $returnResult | |
* @return bool|mixed | |
*/ | |
public function evaluate($other, $description = '', $returnResult = FALSE) | |
{ | |
$success = false; | |
if($this->matches($other) && $this->constraint->evaluate($this->pathValue, $description, TRUE)) { | |
$success = true; | |
} | |
if ($returnResult) { | |
return $success; | |
} | |
if (!$success) { | |
$this->fail($other, $description); | |
} | |
} | |
/** | |
* Check if $other is an array and contains all the keys specified in $this->path | |
* | |
* @param mixed $other | |
* @return bool | |
*/ | |
protected function matches($other) | |
{ | |
if(!is_array($other)) { | |
return false; | |
} | |
$pointer = $other; | |
foreach($this->path as $p) { | |
if(!isset($pointer[$p])) { | |
return false; | |
} | |
$pointer = $pointer[$p]; | |
} | |
$this->pathMatches = true; | |
$this->pathValue = $pointer; | |
return true; | |
} | |
/** | |
* Depending on the type of failure, choose different values for $other | |
* | |
* @param mixed $other | |
* @param string $description | |
* @param PHPUnit_Framework_ComparisonFailure $comparisonFailure | |
*/ | |
protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) | |
{ | |
if($this->pathMatches) { | |
parent::fail($this->pathValue, $description, $comparisonFailure); | |
} | |
else { | |
parent::fail($other, $description, $comparisonFailure); | |
} | |
} | |
/** | |
* Returns a string representation of the object. | |
* | |
* @return string | |
*/ | |
public function toString() | |
{ | |
if($this->pathMatches) { | |
return $this->constraint->toString(); | |
} | |
else { | |
$keys = implode('', array_map(function($v){ return "[$v]"; }, $this->path)); | |
return "has nested key path ". $keys; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment