/**
* Create the mock class for the supplied definition.
*
* @param MockDefinition $definition The definition.
* @param bool $createNew True if a new class should be created even when a compatible one exists.
*
* @return ReflectionClass The class.
* @throws MockException If the mock generation fails.
*/
public function createMockClass(MockDefinition $definition, $createNew = false)
{
$signature = $definition->signature();
if (!$createNew) {
foreach ($this->definitions as $tuple) {
if ($signature === $tuple[0]) {
return $tuple[1];
}
}
}
$className = $this->generator->generateClassName($definition);
if (class_exists($className, false)) {
throw new ClassExistsException($className);
}
$source = $this->generator->generate($definition, $className);
$reporting = error_reporting(E_ERROR | E_COMPILE_ERROR);
$error = null;
try {
eval($source);
} catch (ParseError $e) {
$error = new MockGenerationFailedException($className, $definition, $source, error_get_last(), $e);
// @codeCoverageIgnoreStart
} catch (ParseException $e) {
$error = new MockGenerationFailedException($className, $definition, $source, error_get_last(), $e);
} catch (Throwable $error) {
// re-thrown after cleanup
} catch (Exception $error) {
// re-thrown after cleanup
}
// @codeCoverageIgnoreEnd
error_reporting($reporting);
if ($error) {
throw $error;
}
if (!class_exists($className, false)) {
// @codeCoverageIgnoreStart
throw new MockGenerationFailedException($className, $definition, $source, error_get_last());
// @codeCoverageIgnoreEnd
}
$class = new ReflectionClass($className);
$customMethods = array();
foreach ($definition->customStaticMethods() as $methodName => $method) {
$customMethods[strtolower($methodName)] = $method[0];
}
foreach ($definition->customMethods() as $methodName => $method) {
$customMethods[strtolower($methodName)] = $method[0];
}
$customMethodsProperty = $class->getProperty('_customMethods');
$customMethodsProperty->setAccessible(true);
$customMethodsProperty->setValue(null, $customMethods);
$this->handleFactory->staticHandle($class);
$this->definitions[] = array($signature, $class);
return $class;
}