/** * Create a mock iterator over the given array. * * @param array $a * @param string $class The class to use for the mock, should be/implement/extend Iterator * @param boolean $complete Whether or not to build a complete iteration. This is * used when an exception/break is expected in the middle of the iteration. * @param integer $numElms The number of elements that should be iterated in the case of an * incomplete iteration. */ function mockIteratorOver($a, $class = 'Iterator', $complete = true, $numElms = null) { if ($complete === false && $numElms === null) { throw new Exception("Must provide a number of elements for an " . "incomplete iteration"); } if ($complete) { $numElms = count($a); } $m = \Mockery::mock($class); // The iterator will receive a call to `rewind` with no arguments $m->shouldReceive('rewind')->withNoArgs(); // The iterator will receive a call to `valid` for each element in the array // and return true to indicate that that iteration should continue as well as // one last time returning false to indicate the end of the iteration $validVals = array(); for ($i = 0; $i < $numElms; $i++) { $validVals[] = true; } if ($complete) { $validVals[] = false; } $exp = $m->shouldReceive('valid')->withNoArgs()->times(count($validVals)); call_user_func_array(array($exp, 'andReturn'), $validVals); // The iterator will receive a call to current for each element in the given // array $currentVals = array_values($a); if (!$complete) { $currentVals = array_slice($currentVals, 0, $numElms); } $exp = $m->shouldReceive('current')->withNoArgs()->times($numElms); call_user_func_array(array($exp, 'andReturn'), $currentVals); // The iterator will receive a call to key for each element in the given array $keyVals = array_keys($a); if (!$complete) { $keyVals = array_slice($keyVals, 0, $numElms); } $exp = $m->shouldReceive('key')->withNoArgs()->times($numElms); call_user_func_array(array($exp, 'andReturn'), array_keys($a)); // The iterator will be advanced for each element in the array $m->shouldReceive('next')->withNoArgs()->times(($complete ? $numElms : $numElms - 1)); return $m; }