aboutsummaryrefslogtreecommitdiffstats
path: root/Praspel.php
diff options
context:
space:
mode:
authorIvan Enderlin <ivan.enderlin@hoa-project.net>2013-11-05 10:02:48 +0100
committerIvan Enderlin <ivan.enderlin@hoa-project.net>2013-11-05 15:35:27 +0100
commit750cdea1d3476eaa8b2b5014ed78ec40d22e3a0a (patch)
treeb1dc5b6415c518716dfad6c6e291217968731e0c /Praspel.php
parent88fb5a499ce18d537c275c2abfd79c34ca91f112 (diff)
downloadPraspel-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.php706
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