Chris@0: proxyBuilder = new ProxyBuilder(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildProxyClassName Chris@0: */ Chris@0: public function testBuildProxyClassName() { Chris@0: $class_name = $this->proxyBuilder->buildProxyClassName('Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod'); Chris@0: $this->assertEquals('Drupal\Tests\ProxyClass\Component\ProxyBuilder\TestServiceNoMethod', $class_name); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildProxyClassName Chris@0: */ Chris@0: public function testBuildProxyClassNameForModule() { Chris@0: $class_name = $this->proxyBuilder->buildProxyClassName('Drupal\views_ui\ParamConverter\ViewUIConverter'); Chris@0: $this->assertEquals('Drupal\views_ui\ProxyClass\ParamConverter\ViewUIConverter', $class_name); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildProxyNamespace Chris@0: */ Chris@0: public function testBuildProxyNamespace() { Chris@0: $class_name = $this->proxyBuilder->buildProxyNamespace('Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod'); Chris@0: $this->assertEquals('Drupal\Tests\ProxyClass\Component\ProxyBuilder', $class_name); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests the basic methods like the constructor and the lazyLoadItself method. Chris@0: * Chris@0: * @covers ::build Chris@0: * @covers ::buildConstructorMethod Chris@0: * @covers ::buildLazyLoadItselfMethod Chris@0: */ Chris@0: public function testBuildNoMethod() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: $this->assertEquals($this->buildExpectedClass($class, ''), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildMethod Chris@0: * @covers ::buildMethodBody Chris@0: */ Chris@0: public function testBuildSimpleMethod() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceSimpleMethod'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: Chris@0: $method_body = <<<'EOS' Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function method() Chris@0: { Chris@0: return $this->lazyLoadItself()->method(); Chris@0: } Chris@0: Chris@0: EOS; Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildMethod Chris@0: * @covers ::buildParameter Chris@0: * @covers ::buildMethodBody Chris@0: */ Chris@0: public function testBuildMethodWithParameter() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceMethodWithParameter'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: Chris@0: $method_body = <<<'EOS' Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function methodWithParameter($parameter) Chris@0: { Chris@0: return $this->lazyLoadItself()->methodWithParameter($parameter); Chris@0: } Chris@0: Chris@0: EOS; Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildMethod Chris@0: * @covers ::buildParameter Chris@0: * @covers ::buildMethodBody Chris@0: */ Chris@0: public function testBuildComplexMethod() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceComplexMethod'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: Chris@0: // @todo Solve the silly linebreak for array() Chris@0: $method_body = <<<'EOS' Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function complexMethod($parameter, callable $function, \Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod $test_service = NULL, array &$elements = array ( Chris@0: )) Chris@0: { Chris@0: return $this->lazyLoadItself()->complexMethod($parameter, $function, $test_service, $elements); Chris@0: } Chris@0: Chris@0: EOS; Chris@0: Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildMethod Chris@0: * @covers ::buildMethodBody Chris@0: */ Chris@0: public function testBuildReturnReference() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceReturnReference'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: Chris@0: // @todo Solve the silly linebreak for array() Chris@0: $method_body = <<<'EOS' Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function &returnReference() Chris@0: { Chris@0: return $this->lazyLoadItself()->returnReference(); Chris@0: } Chris@0: Chris@0: EOS; Chris@0: Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildMethod Chris@0: * @covers ::buildParameter Chris@0: * @covers ::buildMethodBody Chris@0: */ Chris@0: public function testBuildWithInterface() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithInterface'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: Chris@0: $method_body = <<<'EOS' Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function testMethod($parameter) Chris@0: { Chris@0: return $this->lazyLoadItself()->testMethod($parameter); Chris@0: } Chris@0: Chris@0: EOS; Chris@0: Chris@0: $interface_string = ' implements \Drupal\Tests\Component\ProxyBuilder\TestInterface'; Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body, $interface_string), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::build Chris@0: */ Chris@0: public function testBuildWithNestedInterface() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithChildInterfaces'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: $method_body = ''; Chris@0: Chris@0: $interface_string = ' implements \Drupal\Tests\Component\ProxyBuilder\TestChildInterface'; Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body, $interface_string), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildMethod Chris@0: * @covers ::buildParameter Chris@0: * @covers ::buildMethodBody Chris@0: */ Chris@0: public function testBuildWithProtectedAndPrivateMethod() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithProtectedMethods'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: Chris@0: $method_body = <<<'EOS' Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function testMethod($parameter) Chris@0: { Chris@0: return $this->lazyLoadItself()->testMethod($parameter); Chris@0: } Chris@0: Chris@0: EOS; Chris@0: Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::buildMethod Chris@0: * @covers ::buildParameter Chris@0: * @covers ::buildMethodBody Chris@0: */ Chris@0: public function testBuildWithPublicStaticMethod() { Chris@0: $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithPublicStaticMethod'; Chris@0: Chris@0: $result = $this->proxyBuilder->build($class); Chris@0: Chris@0: // Ensure that the static method is not wrapped. Chris@0: $method_body = <<<'EOS' Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public static function testMethod($parameter) Chris@0: { Chris@0: \Drupal\Tests\Component\ProxyBuilder\TestServiceWithPublicStaticMethod::testMethod($parameter); Chris@0: } Chris@0: Chris@0: EOS; Chris@0: Chris@0: $this->assertEquals($this->buildExpectedClass($class, $method_body), $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Constructs the expected class output. Chris@0: * Chris@0: * @param string $expected_methods_body Chris@0: * The expected body of decorated methods. Chris@0: * Chris@0: * @return string Chris@0: * The code of the entire proxy. Chris@0: */ Chris@0: protected function buildExpectedClass($class, $expected_methods_body, $interface_string = '') { Chris@0: $namespace = ProxyBuilder::buildProxyNamespace($class); Chris@0: $reflection = new \ReflectionClass($class); Chris@0: $proxy_class = $reflection->getShortName(); Chris@0: Chris@0: $expected_string = <<<'EOS' Chris@0: Chris@0: namespace {{ namespace }} { Chris@0: Chris@0: /** Chris@0: * Provides a proxy class for \{{ class }}. Chris@0: * Chris@0: * @see \Drupal\Component\ProxyBuilder Chris@0: */ Chris@0: class {{ proxy_class }}{{ interface_string }} Chris@0: { Chris@0: Chris@0: /** Chris@0: * The id of the original proxied service. Chris@0: * Chris@0: * @var string Chris@0: */ Chris@0: protected $drupalProxyOriginalServiceId; Chris@0: Chris@0: /** Chris@0: * The real proxied service, after it was lazy loaded. Chris@0: * Chris@0: * @var \{{ class }} Chris@0: */ Chris@0: protected $service; Chris@0: Chris@0: /** Chris@0: * The service container. Chris@0: * Chris@0: * @var \Symfony\Component\DependencyInjection\ContainerInterface Chris@0: */ Chris@0: protected $container; Chris@0: Chris@0: /** Chris@0: * Constructs a ProxyClass Drupal proxy object. Chris@0: * Chris@0: * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Chris@0: * The container. Chris@0: * @param string $drupal_proxy_original_service_id Chris@0: * The service ID of the original service. Chris@0: */ Chris@0: public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $drupal_proxy_original_service_id) Chris@0: { Chris@0: $this->container = $container; Chris@0: $this->drupalProxyOriginalServiceId = $drupal_proxy_original_service_id; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Lazy loads the real service from the container. Chris@0: * Chris@0: * @return object Chris@0: * Returns the constructed real service. Chris@0: */ Chris@0: protected function lazyLoadItself() Chris@0: { Chris@0: if (!isset($this->service)) { Chris@0: $this->service = $this->container->get($this->drupalProxyOriginalServiceId); Chris@0: } Chris@0: Chris@0: return $this->service; Chris@0: } Chris@0: {{ expected_methods_body }} Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: EOS; Chris@0: Chris@0: $expected_methods_body = implode("\n", array_map(function ($value) { Chris@0: if ($value === '') { Chris@0: return $value; Chris@0: } Chris@0: return " $value"; Chris@0: }, explode("\n", $expected_methods_body))); Chris@0: Chris@0: $expected_string = str_replace('{{ proxy_class }}', $proxy_class, $expected_string); Chris@0: $expected_string = str_replace('{{ namespace }}', $namespace, $expected_string); Chris@0: $expected_string = str_replace('{{ class }}', $class, $expected_string); Chris@0: $expected_string = str_replace('{{ expected_methods_body }}', $expected_methods_body, $expected_string); Chris@0: $expected_string = str_replace('{{ interface_string }}', $interface_string, $expected_string); Chris@0: Chris@0: return $expected_string; Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceNoMethod { Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceSimpleMethod { Chris@0: Chris@0: public function method() { Chris@0: Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceMethodWithParameter { Chris@0: Chris@0: public function methodWithParameter($parameter) { Chris@0: Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceComplexMethod { Chris@0: Chris@0: public function complexMethod($parameter, callable $function, TestServiceNoMethod $test_service = NULL, array &$elements = []) { Chris@0: Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceReturnReference { Chris@0: Chris@0: public function &returnReference() { Chris@0: Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: interface TestInterface { Chris@0: Chris@0: public function testMethod($parameter); Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceWithInterface implements TestInterface { Chris@0: Chris@0: public function testMethod($parameter) { Chris@0: Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceWithProtectedMethods { Chris@0: Chris@0: public function testMethod($parameter) { Chris@0: Chris@0: } Chris@0: Chris@0: protected function protectedMethod($parameter) { Chris@0: Chris@0: } Chris@0: Chris@0: protected function privateMethod($parameter) { Chris@0: Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceWithPublicStaticMethod { Chris@0: Chris@0: public static function testMethod($parameter) { Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: interface TestBaseInterface { Chris@0: Chris@0: } Chris@0: Chris@0: interface TestChildInterface extends TestBaseInterface { Chris@0: Chris@0: } Chris@0: Chris@0: class TestServiceWithChildInterfaces implements TestChildInterface { Chris@0: Chris@0: }