public function testStageRunning() { $functionsCalled = []; $tiersByStage = new ExecutableListByTier(); $fn2 = function () use(&$functionsCalled) { $functionsCalled[2] = true; }; $fn0 = function () use(&$functionsCalled, $tiersByStage, $fn2) { $functionsCalled[0] = true; $tiersByStage->addExecutable(4, $fn2); }; $fn1 = function () use(&$functionsCalled) { $functionsCalled[1] = true; }; $tiersByStage->addExecutable(2, $fn0); $tiersByStage->addExecutable(2, $fn1); $injector = new Injector(); foreach ($tiersByStage as $appStage => $tiersForStage) { foreach ($tiersForStage as $tier) { $injector->execute($tier); } } $this->assertArrayHasKey(0, $functionsCalled); $this->assertArrayHasKey(1, $functionsCalled); $this->assertArrayHasKey(2, $functionsCalled); }
public function testExecutable() { $execListByTier = new ExecutableListByTier(); $count = 0; $fn1Count = null; $fn2Count = null; $fn3Count = null; $fn2bCount = null; $fn2b = function () use(&$count, &$fn2bCount) { $fn2bCount = $count; $count++; }; $fn1 = function () use(&$count, &$fn1Count) { $fn1Count = $count; $count++; }; $fn2 = function () use(&$count, &$fn2Count, $execListByTier, $fn2b) { $fn2Count = $count; $count++; $execListByTier->addNextStageTier($fn2b); }; $fn3 = function () use(&$count, &$fn3Count) { $fn3Count = $count; $count++; }; $execListByTier->addExecutable(15, $fn3); $execListByTier->addExecutable(5, $fn1); $execListByTier->addExecutable(10, $fn2); $order = []; $execPosition = []; foreach ($execListByTier as $tier => $execList) { $order[] = $tier; foreach ($execList as $position => $exec) { /** @var $exec callable */ $exec(); $execPosition[] = $position; } } //This checks that the fns were run in the correct order. $this->assertEquals(0, $fn1Count); $this->assertEquals(1, $fn2Count); $this->assertEquals(2, $fn2bCount); $this->assertEquals(3, $fn3Count); //Check that the things were ordered correctly. $this->assertEquals([5, 10, 11, 15], $order); //Check that the executables were the first item in each tier $this->assertEquals([0, 0, 0, 0], $execPosition); }
/** * @param $result mixed The result produced by running the previous executable. * @param Executable $executable The executable that was just run to produce * the result. * @return int * @throws TierException * @throws \Auryn\ConfigException */ protected function processResult($result, Executable $executable) { // If it's a new Tier to run, setup the next loop. if ($result instanceof InjectionParams) { $result->addToInjector($this->injector); return self::PROCESS_CONTINUE; } // If it's a new Tier to run, setup the next loop. if ($result instanceof Executable) { $this->executableListByTier->addExecutable($result); return self::PROCESS_CONTINUE; } if ($result === null && $executable->isAllowedToReturnNull() === true) { return self::PROCESS_CONTINUE; } // if (is_array($result) === true && // count($result) !== 0) { // //It's an array of tiers to run. // foreach ($result as $executableOrCallable) { // if (($executableOrCallable instanceof Executable) === true) { // $this->executableListByTier->addExecutable($executableOrCallable); // continue; // } // else if (is_callable($executableOrCallable) === true) { // $newExecutable = new Executable($executableOrCallable); // $this->executableListByTier->addExecutable($newExecutable); // continue; // } // // throw InvalidReturnException::getWrongTypeException($result, $executable); // } // return self::PROCESS_CONTINUE; // } if ($result === false) { // The executed tier wasn't able to handle it e.g. a caching layer // There should be another tier to execute in this stage. return self::PROCESS_CONTINUE; } // If the $result is an expected product share it for further stages foreach ($this->expectedProducts as $expectedProduct => $created) { if ($result instanceof $expectedProduct) { if (is_subclass_of($result, $expectedProduct) === true) { //product is a sub-class of the expected product. Setup an //alias for it $this->injector->alias($expectedProduct, get_class($result)); } $this->expectedProducts[$expectedProduct] = true; $this->injector->share($result); return self::PROCESS_CONTINUE; } } if ($result === self::PROCESS_CONTINUE || $result === self::PROCESS_END) { return $result; } // Otherwise it's an error throw InvalidReturnException::getWrongTypeException($result, $executable); }
public function testExecutable() { $execListByTier = new ExecutableListByTier(); $count = 0; $fn1Count = null; $fn2Count = null; $fn3Count = null; $fn2bCount = null; $fn2b = function () use(&$count, &$fn2bCount) { $fn2bCount = $count; $count++; }; $fn1 = function () use(&$count, &$fn1Count) { $fn1Count = $count; $count++; }; $fn2 = function () use(&$count, &$fn2Count, $execListByTier, $fn2b) { $fn2Count = $count; $count++; $execListByTier->addExecutable(new Executable($fn2b)); }; $fn3 = function () use(&$count, &$fn3Count) { $fn3Count = $count; $count++; }; $execListByTier->addExecutableToTier(15, $fn3); $execListByTier->addExecutableToTier(5, $fn1); $execListByTier->addExecutableToTier(10, $fn2); $order = []; $execPosition = []; foreach ($execListByTier as $tier => $executableList) { $order[] = $tier; foreach ($executableList as $position => $executable) { $callable = $executable->getCallable(); if (is_callable($callable) === false) { $this->fail("Callable returned by executable apparently isn't."); } call_user_func($callable); $execPosition[] = $position; } } //This checks that the fns were run in the correct order. $this->assertEquals(0, $fn1Count); $this->assertEquals(1, $fn2Count); $this->assertEquals(2, $fn2bCount); $this->assertEquals(3, $fn3Count); //Check that the things were ordered correctly. $this->assertEquals([5, 10, 11, 15], $order); //Check that the executables were the first item in each tier $this->assertEquals([0, 0, 0, 0], $execPosition); }
/** * @param $tier * @param $executable */ public function addExecutable($tier, $executable) { $this->executableListByTier->addExecutable($tier, $executable); }