aboutsummaryrefslogtreecommitdiffstats
path: root/Praspel.php
diff options
context:
space:
mode:
authorIvan Enderlin <ivan.enderlin@hoa-project.net>2013-06-11 21:12:12 +0200
committerIvan Enderlin <ivan.enderlin@hoa-project.net>2013-06-11 21:12:12 +0200
commit832293abb75a8f4ad395f386011ee506dbd97c74 (patch)
tree5bc5a3b1c471f2ac114192c42c94aff1f9ac5b43 /Praspel.php
parent3f262edf4890e6e9a438288d716d2d583fb65562 (diff)
downloadPraspel-832293abb75a8f4ad395f386011ee506dbd97c74.zip
Praspel-832293abb75a8f4ad395f386011ee506dbd97c74.tar.gz
Praspel-832293abb75a8f4ad395f386011ee506dbd97c74.tar.bz2
The RAC now verifies @behavior and @default.
Diffstat (limited to 'Praspel.php')
-rw-r--r--Praspel.php152
1 files changed, 112 insertions, 40 deletions
diff --git a/Praspel.php b/Praspel.php
index ea8e3b4..4ebce28 100644
--- a/Praspel.php
+++ b/Praspel.php
@@ -167,6 +167,7 @@ class Praspel {
public function evaluate ( ) {
// Start.
+ $verdict = true;
$callable = $this->getCallable();
$reflection = $callable->getReflection();
$specification = $this->getSpecification();
@@ -202,19 +203,12 @@ class Praspel {
$arguments[$name] = $parameter->getDefaultValue();
}
- // Check precondition.
- $precondition = true;
-
- if(true === $specification->clauseExists('requires')) {
-
- $requires = $specification->getClause('requires');
- $precondition = $this->checkClause(
- $requires,
- $arguments,
- $exceptions,
- __NAMESPACE__ . '\Exception\Failure\Precondition'
- );
- }
+ $behavior = $specification;
+ $verdict &= $this->checkBehavior(
+ $behavior,
+ $arguments,
+ $exceptions
+ );
if(0 < count($exceptions))
throw $exceptions;
@@ -231,31 +225,31 @@ class Praspel {
$return = $reflection->invokeArgs($_object, $arguments);
}
- // Check normal postcondition.
- $postcondition = true;
+ do {
- if(true === $specification->clauseExists('ensures')) {
+ // Check normal postcondition.
+ if(true === $behavior->clauseExists('ensures')) {
- $ensures = $specification->getClause('ensures');
- $arguments['\result'] = $return;
- $postcondition = $this->checkClause(
- $ensures,
- $arguments,
- $exceptions,
- __NAMESPACE__ . '\Exception\Failure\Postcondition'
- );
- }
+ $ensures = $behavior->getClause('ensures');
+ $arguments['\result'] = $return;
+ $verdict &= $this->checkClause(
+ $ensures,
+ $arguments,
+ $exceptions,
+ __NAMESPACE__ . '\Exception\Failure\Postcondition'
+ );
+ }
+
+ } while(null !== $behavior = $behavior->getParent());
}
catch ( \Exception $exception ) {
// Check exceptional postcondition.
- $postcondition = true;
-
- if(true === $specification->clauseExists('throwable')) {
+ if(true === $behavior->clauseExists('throwable')) {
- $throwable = $specification->getClause('throwable');
- $arguments['\result'] = $exception;
- $postcondition = $this->checkExceptionalClause(
+ $throwable = $behavior->getClause('throwable');
+ $arguments['\result'] = $exception;
+ $verdict &= $this->checkExceptionalClause(
$throwable,
$arguments,
$exceptions,
@@ -267,8 +261,86 @@ class Praspel {
if(0 < count($exceptions))
throw $exceptions;
- // Verdict.
- return $precondition && $postcondition;
+ 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.
+ * @return bool
+ * @throw \Hoa\Praspel\Exception
+ */
+ protected function checkBehavior ( Model\Behavior &$behavior,
+ Array &$data,
+ Exception\Group $exceptions ) {
+
+ $verdict = true;
+
+ // Check precondition.
+ if(true === $behavior->clauseExists('requires')) {
+
+ $requires = $behavior->getClause('requires');
+ $verdict = $this->checkClause(
+ $requires,
+ $data,
+ $exceptions,
+ __NAMESPACE__ . '\Exception\Failure\Precondition'
+ );
+
+ 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 does not verify data.',
+ 2, $_behavior->getIdentifier());
+
+ $_verdict = $this->checkBehavior(
+ $_behavior,
+ $data,
+ $_exceptions
+ );
+
+ if(true === $_verdict)
+ break;
+
+ $exceptions[] = $_exceptions;
+ }
+
+ if(false === $_verdict) {
+
+ if(true === $behavior->clauseExists('default')) {
+
+ $exceptions->cancelTransaction();
+ $_verdict = true;
+ $behavior = $behavior->getClause('default');
+ }
+ else
+ $exceptions->commitTransaction();
+ }
+ else {
+
+ $exceptions->cancelTransaction();
+ $behavior = $_behavior;
+ }
+
+ $verdict &= $_verdict;
+ }
+
+ return $verdict;
}
/**
@@ -293,7 +365,7 @@ class Praspel {
if(false === array_key_exists($name, $data)) {
$exceptions[] = new $exception(
- 'Variable %s has no value and is required.', 0, $name);
+ 'Variable %s has no value and is required.', 3, $name);
continue;
}
@@ -303,7 +375,7 @@ class Praspel {
if(false === $_verdict)
$exceptions[] = new $exception(
'Variable %s does not verify the constraint %s.',
- 0,
+ 4,
array($name, $this->getVisitorPraspel()->visit($variable)));
$verdict = $_verdict && $verdict;
@@ -325,9 +397,9 @@ class Praspel {
* @throw \Hoa\Praspel\Exception
*/
protected function checkExceptionalClause ( Model\Throwable $clause,
- Array &$data,
+ Array &$data,
Exception\Group $exceptions,
- $exception ) {
+ $exception ) {
$verdict = false;
@@ -358,7 +430,7 @@ class Praspel {
if(false === $verdict)
$exceptions[] = new $exception(
'The exception %s has been thrown and it is not specified.',
- 0, array(get_class($data['\result'])));
+ 5, array(get_class($data['\result'])));
return $verdict;
}
@@ -517,14 +589,14 @@ class Praspel {
if(0 === $i)
throw new Exception\Generic(
'Not able to extract Praspel from the following ' .
- 'comment:' . "\n" . '%s', 1, $comment);
+ 'comment:' . "\n" . '%s', 5, $comment);
$i = preg_match_all('#^[\s\*]*\s*\*\s?([^\n]*)$#m', $matches[1], $maatches);
if(0 === $i)
throw new Exception\Generic(
'Not able to extract Praspel from the following ' .
- 'comment:' . "\n" . '%s', 2, $comment);
+ 'comment:' . "\n" . '%s', 6, $comment);
return trim(implode("\n", $maatches[1]));
}