/**
 * returns sequence of parameters of a function or method
 *
 * @param   string|object|array|\ReflectionFunctionAbstract  $classOrFunction  something that references a function or a class
 * @param   string                                           $methodName       optional  name of method in case first param references a class
 * @return  \stubbles\sequence\Sequence
 * @throws  \InvalidArgumentException
 * @since   5.3.0
 */
function parametersOf($classOrFunction, string $methodName = null) : Sequence
{
    if (!$classOrFunction instanceof \ReflectionFunctionAbstract) {
        $function = reflect($classOrFunction, $methodName);
        if (!$function instanceof \ReflectionFunctionAbstract) {
            throw new \InvalidArgumentException('Given function must be a function name, a method' . ' reference or an instance of \\ReflectionFunctionAbstract');
        }
    } else {
        $function = $classOrFunction;
    }
    return Sequence::of($function->getParameters())->mapKeys(function ($key, \ReflectionParameter $parameter) {
        return $parameter->getName();
    });
}
 /**
  * @test
  */
 public function toMapPassesKeyAndValueWhenNoSelectorProvided()
 {
     assert(Sequence::of($this->people)->collect()->inMap(), equals($this->people));
 }
 /**
  * @test
  */
 public function exportsSequenceAsStringRepresentation()
 {
     assert(Provides::values([1])->describeValue(exporter(), Sequence::of([])), equals(Sequence::class . ' of array'));
 }
 /**
  * @test
  */
 public function partitioningByWithSum()
 {
     assert(Sequence::of($this->people)->collect()->inPartitions(function (Employee $e) {
         return $e->years() > 10;
     }, Collector::forSum(function (Employee $e) {
         return $e->years();
     })), equals([true => 29, false => 4]));
 }
 /**
  * @test
  * @since  5.3.2
  */
 public function canBeSerializedToJson()
 {
     assert(json_encode(Sequence::of(['one' => 1, 2, 'three' => 3, 4])), equals('{"one":1,"0":2,"three":3,"1":4}'));
 }
 /**
  * @test
  */
 public function containsReferenceToBothLimitAndSkippedElements()
 {
     assert((string) Sequence::infinite(1, function ($i) {
         return ++$i;
     })->skip(2)->limit(3), equals(Sequence::class . ' starting at 1 continued by a lambda function' . ' skipped until offset 2 limited to 3 elements'));
 }