diff options
author | Ivan Enderlin <ivan.enderlin@hoa-project.net> | 2013-11-05 10:02:48 +0100 |
---|---|---|
committer | Ivan Enderlin <ivan.enderlin@hoa-project.net> | 2013-11-05 15:35:27 +0100 |
commit | 750cdea1d3476eaa8b2b5014ed78ec40d22e3a0a (patch) | |
tree | b1dc5b6415c518716dfad6c6e291217968731e0c /Praspel.php | |
parent | 88fb5a499ce18d537c275c2abfd79c34ca91f112 (diff) | |
download | Praspel-750cdea1d3476eaa8b2b5014ed78ec40d22e3a0a.zip Praspel-750cdea1d3476eaa8b2b5014ed78ec40d22e3a0a.tar.gz Praspel-750cdea1d3476eaa8b2b5014ed78ec40d22e3a0a.tar.bz2 |
Support $this.
Create the sub-library `Hoa\Praspel\AssertionChecker` and introduce
$this support through “implicit variables”.
Diffstat (limited to 'Praspel.php')
-rw-r--r-- | Praspel.php | 706 |
1 files changed, 0 insertions, 706 deletions
diff --git a/Praspel.php b/Praspel.php index 553e0e4..bb6b33d 100644 --- a/Praspel.php +++ b/Praspel.php @@ -39,41 +39,6 @@ namespace { from('Hoa') /** - * \Hoa\Praspel\Exception\Generic - */ --> import('Praspel.Exception.Generic') - -/** - * \Hoa\Praspel\Exception\Group - */ --> import('Praspel.Exception.Group') - -/** - * \Hoa\Praspel\Exception\Failure\Precondition - */ --> import('Praspel.Exception.Failure.Precondition') - -/** - * \Hoa\Praspel\Exception\Failure\Postcondition - */ --> import('Praspel.Exception.Failure.Postcondition') - -/** - * \Hoa\Praspel\Exception\Failure\Exceptional - */ --> import('Praspel.Exception.Failure.Exceptional') - -/** - * \Hoa\Praspel\Exception\Failure\Invariant - */ --> import('Praspel.Exception.Failure.Invariant') - -/** - * \Hoa\Praspel\Exception\Failure\InternalPrecondition - */ --> import('Praspel.Exception.Failure.InternalPrecondition') - -/** * \Hoa\Praspel\Trace */ -> import('Praspel.Trace') @@ -84,11 +49,6 @@ from('Hoa') -> import('Praspel.Visitor.Interpreter') /** - * \Hoa\Praspel\Visitor\Praspel - */ --> import('Praspel.Visitor.Praspel') - -/** * \Hoa\Compiler\Llk */ -> import('Compiler.Llk.~') @@ -115,672 +75,6 @@ namespace Hoa\Praspel { class Praspel { /** - * Specification. - * - * @var \Hoa\Praspel\Model\Specification object - */ - protected $_specification = null; - - /** - * Data of the specification. - * - * @var \Hoa\Praspel array - */ - protected $_data = null; - - /** - * Whether we are able to automatically generate data. - * - * @var \Hoa\Praspel bool - */ - protected $_generateData = false; - - /** - * Callable to validate and verify. - * - * @var \Hoa\Core\Consistency\Xcallable object - */ - protected $_callable = null; - - /** - * Visitor Praspel. - * - * @var \Hoa\Praspel\Visitor\Praspel object - */ - protected $_visitorPraspel = null; - - - - /** - * Construct. - * - * @access public - * @param \Hoa\Praspel\Model\Specification $specification Specification. - * @param \Hoa\Core\Consistency\Xcallable $callable Callable. - * @param bool $genrateData Generate data. - * @return void - */ - public function __construct ( Model\Specification $specification, - \Hoa\Core\Consistency\Xcallable $callable, - $generateData = false ) { - - $this->setSpecification($specification); - $this->setCallable($callable); - $this->automaticallyGenerateData($generateData); - - return; - } - - /** - * Runtime assertion checker. - * - * @access public - * @param \Hoa\Praspel\Trace $trace Trace. - * @return bool - * @throw \Hoa\Praspel\Exception\Generic - * @throw \Hoa\Praspel\Exception\Group - */ - public function evaluate ( &$trace = false ) { - - // Start. - $verdict = true; - $callable = $this->getCallable(); - $reflection = $callable->getReflection(); - $specification = $this->getSpecification(); - $exceptions = new Exception\Group( - 'The Runtime Assertion Checker has detected failures for %s.', - 0, $callable - ); - - if($reflection instanceof \ReflectionMethod) - $reflection->setAccessible(true); - - if(false !== $trace && !($trace instanceof Trace)) - $trace = new Trace(); - - // Prepare data. - if(null === $data = $this->getData()) - if(true === $this->canGenerateData()) - $data = $this->generateData(); - else - throw new Exception\Generic( - 'No data were given. The System Under Test %s needs data ' . - 'to be executed.', 1, $callable); - - $arguments = array(); - $numberOfRequiredArguments = 0; - - foreach($reflection->getParameters() as $parameter) { - - $name = $parameter->getName(); - - if(true === array_key_exists($name, $data)) { - - $arguments[$name] = &$data[$name]; - - if(false === $parameter->isOptional()) - ++$numberOfRequiredArguments; - - continue; - } - - if(false === $parameter->isOptional()) { - - ++$numberOfRequiredArguments; - - // Let the error be caught by a @requires clause. - continue; - } - - $arguments[$name] = $parameter->getDefaultValue(); - } - - // Check invariant. - if(true === $specification->clauseExists('invariant')) { - - $invariant = $specification->getClause('invariant'); - $verdict &= $this->checkClause( - $invariant, - $arguments, - $exceptions, - __NAMESPACE__ . '\Exception\Failure\Invariant', - true, - $trace - ); - - if(0 < count($exceptions)) - throw $exceptions; - } - - // Check requires and behaviors. - $behavior = $specification; - $verdict &= $this->checkBehavior( - $behavior, - $arguments, - $exceptions, - true, - $trace - ); - - if(0 < count($exceptions)) - throw $exceptions; - - $numberOfArguments = count($arguments); - - if($numberOfArguments < $numberOfRequiredArguments) { - - $exceptions[] = new Exception\Failure\Precondition( - 'Callable %s needs %d arguments; %d given.', - 2, array($callable, $numberOfRequiredArguments, $numberOfArguments) - ); - - throw $exceptions; - } - - try { - - // Invoke. - if($reflection instanceof \ReflectionFunction) - $return = $reflection->invokeArgs($arguments); - else { - - $_callback = $callable->getValidCallback(); - $_object = $_callback[0]; - $return = $reflection->invokeArgs($_object, $arguments); - } - - $arguments['\result'] = $return; - $_exceptions = null; - - do { - - $handle = $behavior instanceof Model\Specification - ? $exceptions - : new Exception\Group( - 'Behavior %s is broken.', - 3, $behavior->getIdentifier() - ); - - if(null !== $_exceptions && 0 < count($_exceptions)) - $handle[] = $_exceptions; - - $_exceptions = $handle; - - // Check normal postcondition. - if(true === $behavior->clauseExists('ensures')) { - - $ensures = $behavior->getClause('ensures'); - $verdict &= $this->checkClause( - $ensures, - $arguments, - $_exceptions, - __NAMESPACE__ . '\Exception\Failure\Postcondition', - false, - $trace - ); - } - - } while(null !== $behavior = $behavior->getParent()); - } - catch ( Exception $internalException ) { - - $exceptions[] = new Exception\Failure\InternalPrecondition( - 'The System Under Test has broken an internal contract.', - 4, null, $internalException); - } - catch ( \Exception $exception ) { - - $_verdict = false; - $arguments['\result'] = $exception; - - do { - - // Check exceptional postcondition. - if(true === $behavior->clauseExists('throwable')) { - - $throwable = $behavior->getClause('throwable'); - $_verdict = $this->checkExceptionalClause( - $throwable, - $arguments - ); - } - - } while( false === $_verdict - && null !== $behavior = $behavior->getParent()); - - if(false === $_verdict) - $exceptions[] = new Exception\Failure\Exceptional( - 'The exception %s has been unexpectedly thrown.', - 5, array(get_class($arguments['\result'])) - ); - - $verdict &= $_verdict; - } - - if(0 < count($exceptions)) - throw $exceptions; - - // Check invariant. - if(true === $specification->clauseExists('invariant')) { - - $invariant = $specification->getClause('invariant'); - $verdict &= $this->checkClause( - $invariant, - $arguments, - $exceptions, - __NAMESPACE__ . '\Exception\Failure\Invariant', - true, - $trace - ); - - if(0 < count($exceptions)) - throw $exceptions; - } - - return (bool) $verdict; - } - - /** - * Check behavior clauses. - * - * @access protected - * @param \Hoa\Praspel\Model\Behavior $behavior Behavior clause. - * @param array &$data Data. - * @param \Hoa\Praspel\Exception\Group $exceptions Exceptions group. - * @param bool $assign Assign data to - * variable. - * @param \Hoa\Praspel\Trace $trace Trace. - * @return bool - * @throw \Hoa\Praspel\Exception - */ - protected function checkBehavior ( Model\Behavior $behavior, - Array &$data, - Exception\Group $exceptions, - $assign = false, - $trace = false ) { - - $verdict = true; - - // Check precondition. - if(true === $behavior->clauseExists('requires')) { - - $requires = $behavior->getClause('requires'); - $verdict = $this->checkClause( - $requires, - $data, - $exceptions, - __NAMESPACE__ . '\Exception\Failure\Precondition', - $assign, - $trace - ); - - if(false === $verdict) - return false; - } - - // Check behaviors. - if(true === $behavior->clauseExists('behavior')) { - - $_verdict = false; - $behaviors = $behavior->getClause('behavior'); - $exceptions->beginTransaction(); - - foreach($behaviors as $_behavior) { - - $_exceptions = new Exception\Group( - 'Behavior %s is broken.', - 6, $_behavior->getIdentifier() - ); - - $_trace = null; - - if(!empty($trace)) { - - $_trace = new Model\Behavior($trace); - $_trace->setIdentifier($_behavior->getIdentifier()); - } - - $_verdict = $this->checkBehavior( - $_behavior, - $data, - $_exceptions, - $assign, - $_trace - ); - - if(true === $_verdict) { - - $trace->addClause($_trace); - - break; - } - - $exceptions[] = $_exceptions; - unset($_trace); - } - - if(false === $_verdict) { - - if(true === $behavior->clauseExists('default')) { - - $exceptions->rollbackTransaction(); - $_verdict = true; - $behavior = $behavior->getClause('default'); - } - else - $exceptions->commitTransaction(); - } - else { - - $exceptions->rollbackTransaction(); - $behavior = $_behavior; - } - - $verdict &= $_verdict; - } - - return (bool) $verdict; - } - - /** - * Check a clause. - * - * @access protected - * @param \Hoa\Praspel\Model\Declaration $clause Clause. - * @param array &$data Data. - * @param \Hoa\Praspel\Exception\Group $exceptions Exceptions group. - * @param string $exception Exception to - * throw. - * @param bool $assign Assign data to - * variable. - * @param \Hoa\Praspel\Trace $trace Trace. - * @return bool - * @throw \Hoa\Praspel\Exception - */ - protected function checkClause ( Model\Declaration $clause, Array &$data, - Exception\Group $exceptions, $exception, - $assign = false, - $trace = false ) { - - $verdict = true; - $traceClause = null; - - if(!empty($trace)) - $traceClause = clone $clause; - - foreach($clause as $name => $variable) { - - $_name = $name; - - if('\old(' === substr($name, 0, 5)) - $_name = substr($name, 5, -1); - - if(false === array_key_exists($_name, $data)) { - - $exceptions[] = new $exception( - 'Variable %s is required and has no value.', 5, $name); - - continue; - } - - $datum = &$data[$_name]; - $_verdict = false; - $traceVariable = null; - - if(null !== $traceClause) { - - $traceVariable = clone $variable; - $traceVariableDomains = $traceVariable->getDomains(); - } - - $i = 0; - - foreach($variable->getDomains() as $realdom) { - - if(false === $_verdict && true === $realdom->predicate($datum)) - $_verdict = true; - elseif(null !== $traceClause) - unset($traceVariableDomains[$i--]); - - ++$i; - } - - if(false === $_verdict) { - - if(null !== $traceClause) - unset($traceClause[$name]); - - $exceptions[] = new $exception( - 'Variable %s does not verify the constraint @%s %s.', - 6, - array( - $name, - $clause->getName(), - $this->getVisitorPraspel()->visit($variable) - )); - } - else { - - if(true === $assign) - $variable->setValue($datum); - - if(null !== $traceClause) { - - unset($traceClause[$name]); - $traceClause->addVariable($name, $traceVariable); - } - } - - $verdict &= $_verdict; - } - - if(!empty($trace)) - $trace->addClause($traceClause); - - return (bool) $verdict; - } - - /** - * Check an exceptional clause. - * - * @access protected - * @param \Hoa\Praspel\Model\Throwable $clause Clause. - * @param array &$data Data. - * @return bool - * @throw \Hoa\Praspel\Exception - */ - protected function checkExceptionalClause ( Model\Throwable $clause, - Array &$data ) { - - $verdict = false; - - foreach($clause as $identifier) { - - $_exception = $clause[$identifier]; - $instanceName = $_exception->getInstanceName(); - - if($data['\result'] instanceof $instanceName) { - - $verdict = true; - break; - } - - foreach((array) $_exception->getDisjunction() as $_identifier) { - - $__exception = $clause[$_identifier]; - $_instanceName = $__exception->getInstanceName(); - - if($exception instanceof $_instanceName) { - - $verdict = true; - break; - } - } - } - - return $verdict; - } - - /** - * Set specification. - * - * @access protected - * @param \Hoa\Praspel\Model\Specification $specification Specification. - * @return \Hoa\Praspel\Model\Specification - */ - protected function setSpecification ( Model\Specification $specification ) { - - $old = $this->_specification; - $this->_specification = $specification; - - return $old; - } - - /** - * Get specification. - * - * @access public - * @return \Hoa\Praspel\Model\Specification - */ - public function getSpecification ( ) { - - return $this->_specification; - } - - /** - * Isotropic random generation of data from the @requires clause. - * - * @access public - * @return array - */ - public function generateData ( ) { - - $data = array(); - $behavior = $this->getSpecification(); - - do { - - if(true === $behavior->clauseExists('requires')) { - - foreach($behavior->getClause('requires') as $name => $variable) - $data[$name] = $variable->sample(); - } - - if(false === $behavior->clauseExists('behavior')) - break; - - $behaviors = $behavior->getClause('behavior'); - $count = count($behaviors); - $i = mt_rand(0, $count); - - if($i === $count) { - - if(true === $behavior->clauseExists('default')) - $behavior = $behavior->getClause('default'); - } - else - $behavior = $behaviors->getNth($i); - - } while(true); - - $this->setData($data); - - return $data; - } - - /** - * Enable or disable the automatic data generation. - * - * @access public - * @param bool $generateData Generate data or not. - * @return bool - */ - public function automaticallyGenerateData ( $generateData ) { - - $old = $this->_generateData; - $this->_generateData = $generateData; - - return $old; - } - - /** - * Whether we are able to automatically generate data. - * - * @access public - * @return bool - */ - public function canGenerateData ( ) { - - return $this->_generateData; - } - - /** - * Set data. - * - * @access public - * @param array $data Data. - * @return array - */ - public function setData ( Array $data ) { - - $old = $this->_data; - $this->_data = $data; - - return $old; - } - - /** - * Get data. - * - * @access public - * @return array - */ - public function getData ( ) { - - return $this->_data; - } - - /** - * Set callable. - * - * @access protected - * @param \Hoa\Core\Consistency\Xcallable $callable Callable. - * @return \Hoa\Core\Consistency\Xcallable - */ - protected function setCallable ( \Hoa\Core\Consistency\Xcallable $callable ) { - - $old = $this->_callable; - $this->_callable = $callable; - - return $old; - } - - /** - * Get callable. - * - * @access public - * @return \Hoa\Core\Consistency\Xcallable - */ - public function getCallable ( ) { - - return $this->_callable; - } - - /** - * Get visitor Praspel. - * - * @access protected - * @return \Hoa\Praspel\Visitor\Praspel - */ - protected function getVisitorPraspel ( ) { - - if(null === $this->_visitorPraspel) - $this->_visitorPraspel = new Visitor\Praspel(); - - return $this->_visitorPraspel; - } - - /** * Short interpreter. * * @access public |