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 * @throws InvalidReturnException * @throws TierException * @return int */ private function processResult($result) { // If it's a new Tier to run, setup the next loop. if ($result instanceof Executable) { $this->executableListByTier->addNextStageTier($result); return self::PROCESS_CONTINUE; } if (is_array($result) && count($result) != 0) { //It's an array of tiers to run. foreach ($result as $tier) { if (!$tier instanceof Executable) { throw new InvalidReturnException(self::RETURN_VALUE, $result); } $this->executableListByTier->addNextStageTier($tier); } 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 (strcasecmp($expectedProduct, get_class($result)) !== 0) { //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_END_STAGE; } } if ($result === self::PROCESS_END_STAGE || $result === self::PROCESS_CONTINUE || $result === self::PROCESS_END) { return $result; } // Otherwise it's an error throw InvalidReturnException::getWrongTypeException($result); }