/**
  * @param ExerciseInterface $exercise
  * @return ExerciseInterface
  */
 private function validateExercise(ExerciseInterface $exercise)
 {
     $type = $exercise->getType();
     $requiredInterface = $type->getExerciseInterface();
     if (!$exercise instanceof $requiredInterface) {
         throw InvalidArgumentException::missingImplements($exercise, $requiredInterface);
     }
     return $exercise;
 }
 /**
  * @param array $listeners
  * @return array
  */
 private function mergeListenerGroups(array $listeners)
 {
     $listeners = new Collection($listeners);
     return $listeners->keys()->reduce(function (Collection $carry, $listenerGroup) use($listeners) {
         $events = new Collection($listeners->get($listenerGroup));
         return $events->keys()->reduce(function (Collection $carry, $event) use($events) {
             $listeners = $events->get($event);
             if (!is_array($listeners)) {
                 throw InvalidArgumentException::typeMisMatch('array', $listeners);
             }
             return $carry->set($event, array_merge($carry->get($event, []), $listeners));
         }, $carry);
     }, new Collection())->getArrayCopy();
 }
 /**
  * @param string $requiredCheck
  * @param string $position
  * @throws InvalidArgumentException
  */
 public function requireCheck($requiredCheck, $position)
 {
     if (!$this->checkRepository->has($requiredCheck)) {
         throw new InvalidArgumentException(sprintf('Check: "%s" does not exist', $requiredCheck));
     }
     switch ($position) {
         case static::CHECK_BEFORE:
             $this->checksToRunBefore[] = $this->checkRepository->getByClass($requiredCheck);
             break;
         case static::CHECK_AFTER:
             $this->checksToRunAfter[] = $this->checkRepository->getByClass($requiredCheck);
             break;
         default:
             throw InvalidArgumentException::notValidParameter('position', [static::CHECK_BEFORE, static::CHECK_AFTER], $position);
     }
 }
 /**
  * @param string|CommandArgument $argument
  * @return $this
  */
 public function addArgument($argument)
 {
     if (!is_string($argument) && !$argument instanceof CommandArgument) {
         throw InvalidArgumentException::notValidParameter('argument', ['string', CommandArgument::class], $argument);
     }
     if (is_string($argument)) {
         $argument = new CommandArgument($argument);
     }
     if (count($this->args) === 0) {
         $this->args[] = $argument;
         return $this;
     }
     $previousArgument = end($this->args);
     if ($previousArgument->isOptional() && $argument->isRequired()) {
         throw new InvalidArgumentException(sprintf('A required argument cannot follow an optional argument'));
     }
     $this->args[] = $argument;
     return $this;
 }
 /**
  * @param string $eventName
  * @param array $listeners
  * @param ContainerInterface $container
  * @param EventDispatcher $dispatcher
  * @throws \PhpSchool\PhpWorkshop\Exception\InvalidArgumentException
  */
 private function attachListeners($eventName, array $listeners, ContainerInterface $container, EventDispatcher $dispatcher)
 {
     array_walk($listeners, function ($listener) use($eventName, $dispatcher, $container) {
         if (is_callable($listener)) {
             return $dispatcher->listen($eventName, $listener);
         }
         if (!is_string($listener)) {
             throw new InvalidArgumentException(sprintf('Listener must be a callable or a container entry for a callable service.'));
         }
         if (!$container->has($listener)) {
             throw new InvalidArgumentException(sprintf('Container has no entry named: "%s"', $listener));
         }
         $listener = $container->get($listener);
         if (!is_callable($listener)) {
             throw InvalidArgumentException::typeMisMatch('callable', $listener);
         }
         return $dispatcher->listen($eventName, $listener);
     });
 }
 /**
  * @dataProvider stringifyProvider
  * @param mixed $value
  * @param string $expected
  */
 public function testStringify($value, $expected)
 {
     $this->assertEquals(InvalidArgumentException::stringify($value), $expected);
 }
 public function testExceptionFromNotValidParameterConstructor()
 {
     $e = InvalidArgumentException::notValidParameter('number', [1, 2], 3);
     $this->assertEquals('Parameter: "number" can only be one of: "1", "2" Received: "3"', $e->getMessage());
 }
 /**
  * Queue a specific check to be run when the exercise is verified. When the exercise is verified
  * the check specified as the first argument will also be executed. Throws an `InvalidArgumentException`
  * if the check does not exist in the `CheckRepository`.
  *
  * @param string $requiredCheck The name of the required check.
  * @throws InvalidArgumentException If the check does not exist.
  */
 public function requireCheck($requiredCheck)
 {
     if (!$this->checkRepository->has($requiredCheck)) {
         throw new InvalidArgumentException(sprintf('Check: "%s" does not exist', $requiredCheck));
     }
     $check = $this->checkRepository->getByClass($requiredCheck);
     if ($check instanceof SimpleCheckInterface) {
         switch ($check->getPosition()) {
             case SimpleCheckInterface::CHECK_BEFORE:
                 $this->checksToRunBefore[] = $check;
                 break;
             case SimpleCheckInterface::CHECK_AFTER:
                 $this->checksToRunAfter[] = $check;
                 break;
             default:
                 throw InvalidArgumentException::notValidParameter('position', [SimpleCheckInterface::CHECK_BEFORE, SimpleCheckInterface::CHECK_AFTER], $check->getPosition());
         }
         return;
     }
     if (!$check instanceof ListenableCheckInterface) {
         throw new InvalidArgumentException(sprintf('Check: "%s" is not a listenable check', $requiredCheck));
     }
     $check->attach($this->eventDispatcher);
 }
 public function testExceptionFromMissingImplements()
 {
     $e = InvalidArgumentException::missingImplements(new \stdClass(), Countable::class);
     self::assertEquals('"stdClass" is required to implement "Countable", but it does not', $e->getMessage());
 }