Exemplo n.º 1
0
 /**
  * Precondition: $values should fail $this->assertion
  */
 public function from(array $elements, AssertionFailed $exception)
 {
     $onBadShrink = function () use(&$exception) {
         $this->attempts->increase();
         $this->attempts->ensureLimit($exception);
     };
     $onGoodShrink = function ($elementsAfterShrink, $exceptionAfterShrink) use(&$elements, &$exception) {
         $this->attempts->reset();
         $elements = $elementsAfterShrink;
         $exception = $exceptionAfterShrink;
     };
     $this->timeLimit->start();
     while (!$this->timeLimit->hasBeenReached()) {
         $elementsAfterShrink = $this->generator->shrink($elements);
         if ($elementsAfterShrink === $elements) {
             $onBadShrink();
             continue;
         }
         if (!$this->checkGoodShrinkConditions($elementsAfterShrink)) {
             $onBadShrink();
             continue;
         }
         Evaluation::of($this->assertion)->with($elementsAfterShrink)->onFailure($onGoodShrink)->onSuccess($onBadShrink)->execute();
     }
     throw new \RuntimeException("Eris has reached the time limit for shrinking, here it is presenting the simplest failure case." . PHP_EOL . "If you can afford to spend more time to find a simpler failing input, increase \$this->shrinkingTimeLimit or set it to null to remove it.", -1, $exception);
 }
Exemplo n.º 2
0
 public function __invoke(callable $assertion)
 {
     $sizes = $this->sizes($this->maxSize);
     try {
         for ($iteration = 0; $iteration < $this->iterations; $iteration++) {
             $values = [];
             foreach ($this->generators as $name => $generator) {
                 $currentSizeIndex = $iteration % count($sizes);
                 $value = $generator($sizes[$currentSizeIndex]);
                 $values[] = $value;
             }
             if (!$this->antecedentsAreSatisfied($values)) {
                 continue;
             }
             $this->evaluations++;
             Evaluation::of($assertion)->with($values)->onFailure(function ($values, $exception) use($assertion) {
                 $shrinking = $this->shrinkerFactory->random($this->generators, $assertion);
                 // MAYBE: put into ShrinkerFactory?
                 $shrinking->addGoodShrinkCondition(function (array $values) {
                     return $this->antecedentsAreSatisfied($values);
                 });
                 $shrinking->from($values, $exception);
             })->execute();
         }
     } catch (Exception $e) {
         $wrap = (bool) getenv('ERIS_ORIGINAL_INPUT');
         if ($wrap) {
             $message = "Original input: " . var_export($values, true) . PHP_EOL . "Possibly shrinked input follows." . PHP_EOL;
             throw new RuntimeException($message, -1, $e);
         } else {
             throw $e;
         }
     }
 }
Exemplo n.º 3
0
 public function __invoke(callable $assertion)
 {
     $sizes = Size::withTriangleGrowth($this->maxSize)->limit($this->iterations);
     try {
         $redTestException = null;
         $this->notifyListeners('startPropertyVerification');
         for ($iteration = 0; $iteration < $this->iterations && !$this->terminationConditionsAreSatisfied(); $iteration++) {
             $generatedValues = [];
             $values = [];
             foreach ($this->generators as $name => $generator) {
                 $value = $generator($sizes->at($iteration), $this->rand);
                 if (!$value instanceof GeneratedValue) {
                     throw new RuntimeException("The value returned by a generator should be an instance of GeneratedValue, but it is " . var_export($value, true));
                 }
                 $generatedValues[] = $value;
                 $values[] = $value->unbox();
             }
             $generation = GeneratedValue::fromValueAndInput($values, $generatedValues, 'tuple');
             $this->notifyListeners('newGeneration', $generation->unbox(), $iteration);
             if (!$this->antecedentsAreSatisfied($values)) {
                 continue;
             }
             $this->ordinaryEvaluations++;
             Evaluation::of($assertion)->with($generation)->onFailure(function ($generatedValues, $exception) use($assertion) {
                 $this->notifyListeners('failure', $generatedValues->unbox(), $exception);
                 if (!$this->shrinkingEnabled) {
                     throw $exception;
                 }
                 $shrinking = $this->shrinkerFactory->random($this->generators, $assertion);
                 // MAYBE: put into ShrinkerFactory?
                 $shrinking->addGoodShrinkCondition(function (GeneratedValue $generatedValues) {
                     return $this->antecedentsAreSatisfied($generatedValues->unbox());
                 })->onAttempt(function (GeneratedValue $generatedValues) {
                     $this->notifyListeners('shrinking', $generatedValues->unbox());
                 })->from($generatedValues, $exception);
             })->execute();
         }
     } catch (Exception $e) {
         $redTestException = $e;
         $wrap = (bool) getenv('ERIS_ORIGINAL_INPUT');
         if ($wrap) {
             $message = "Original input: " . var_export($values, true) . PHP_EOL . "Possibly shrinked input follows." . PHP_EOL;
             throw new RuntimeException($message, -1, $e);
         } else {
             throw $e;
         }
     } finally {
         $this->notifyListeners('endPropertyVerification', $this->ordinaryEvaluations, $this->iterations, $redTestException);
     }
 }