Chris@0: assertEquals($expected, $info); Chris@0: } Chris@0: Chris@0: public function infoParserProvider() { Chris@0: // A module provided unit test. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@18: 'name' => static::class, Chris@0: 'group' => 'simpletest', Chris@18: 'groups' => ['simpletest'], Chris@0: 'description' => 'Tests \Drupal\simpletest\TestDiscovery.', Chris@0: 'type' => 'PHPUnit-Unit', Chris@0: ], Chris@0: // Classname. Chris@18: static::class, Chris@0: ]; Chris@0: Chris@0: // A core unit test. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\Tests\Core\DrupalTest', Chris@0: 'group' => 'DrupalTest', Chris@18: 'groups' => ['DrupalTest'], Chris@0: 'description' => 'Tests \Drupal.', Chris@0: 'type' => 'PHPUnit-Unit', Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\Tests\Core\DrupalTest', Chris@0: ]; Chris@0: Chris@0: // Functional PHPUnit test. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\FunctionalTests\BrowserTestBaseTest', Chris@0: 'group' => 'browsertestbase', Chris@18: 'groups' => ['browsertestbase'], Chris@0: 'description' => 'Tests BrowserTestBase functionality.', Chris@0: 'type' => 'PHPUnit-Functional', Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\FunctionalTests\BrowserTestBaseTest', Chris@0: ]; Chris@0: Chris@0: // kernel PHPUnit test. Chris@0: $tests['phpunit-kernel'] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => '\Drupal\Tests\file\Kernel\FileItemValidationTest', Chris@0: 'group' => 'file', Chris@18: 'groups' => ['file'], Chris@0: 'description' => 'Tests that files referenced in file and image fields are always validated.', Chris@0: 'type' => 'PHPUnit-Kernel', Chris@0: ], Chris@0: // Classname. Chris@0: '\Drupal\Tests\file\Kernel\FileItemValidationTest', Chris@0: ]; Chris@0: Chris@0: // Simpletest classes can not be autoloaded in a PHPUnit test, therefore Chris@0: // provide a docblock. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: 'group' => 'simpletest', Chris@18: 'groups' => ['simpletest'], Chris@0: 'description' => 'Tests the Simpletest UI internal browser.', Chris@0: 'type' => 'Simpletest', Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: // Doc block. Chris@0: "/** Chris@0: * Tests the Simpletest UI internal browser. Chris@0: * Chris@0: * @group simpletest Chris@0: */ Chris@0: ", Chris@0: ]; Chris@0: Chris@0: // Test with a different amount of leading spaces. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: 'group' => 'simpletest', Chris@18: 'groups' => ['simpletest'], Chris@0: 'description' => 'Tests the Simpletest UI internal browser.', Chris@0: 'type' => 'Simpletest', Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: // Doc block. Chris@0: "/** Chris@0: * Tests the Simpletest UI internal browser. Chris@0: * Chris@0: * @group simpletest Chris@0: */ Chris@0: */ Chris@0: ", Chris@0: ]; Chris@0: Chris@0: // Make sure that a "* @" inside a string does not get parsed as an Chris@0: // annotation. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: 'group' => 'simpletest', Chris@18: 'groups' => ['simpletest'], Chris@0: 'description' => 'Tests the Simpletest UI internal browser. * @', Chris@0: 'type' => 'Simpletest', Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: // Doc block. Chris@0: "/** Chris@0: * Tests the Simpletest UI internal browser. * @ Chris@0: * Chris@0: * @group simpletest Chris@0: */ Chris@0: ", Chris@0: ]; Chris@0: Chris@0: // Multiple @group annotations. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: 'group' => 'Test', Chris@18: 'groups' => ['Test', 'simpletest'], Chris@0: 'description' => 'Tests the Simpletest UI internal browser.', Chris@0: 'type' => 'Simpletest', Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: // Doc block. Chris@0: "/** Chris@0: * Tests the Simpletest UI internal browser. Chris@0: * Chris@0: * @group Test Chris@0: * @group simpletest Chris@0: */ Chris@0: ", Chris@0: ]; Chris@0: Chris@18: // A great number of @group annotations. Chris@18: $tests['many-group-annotations'] = [ Chris@18: // Expected result. Chris@18: [ Chris@18: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@18: 'group' => 'Test', Chris@18: 'groups' => ['Test', 'simpletest', 'another', 'more', 'many', 'enough', 'whoa'], Chris@18: 'description' => 'Tests the Simpletest UI internal browser.', Chris@18: 'type' => 'Simpletest', Chris@18: ], Chris@18: // Classname. Chris@18: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@18: // Doc block. Chris@18: "/** Chris@18: * Tests the Simpletest UI internal browser. Chris@18: * Chris@18: * @group Test Chris@18: * @group simpletest Chris@18: * @group another Chris@18: * @group more Chris@18: * @group many Chris@18: * @group enough Chris@18: * @group whoa Chris@18: */ Chris@18: ", Chris@18: ]; Chris@18: Chris@0: // @dependencies annotation. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: 'description' => 'Tests the Simpletest UI internal browser.', Chris@0: 'type' => 'Simpletest', Chris@0: 'requires' => ['module' => ['test']], Chris@0: 'group' => 'simpletest', Chris@18: 'groups' => ['simpletest'], Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: // Doc block. Chris@0: "/** Chris@0: * Tests the Simpletest UI internal browser. Chris@0: * Chris@0: * @dependencies test Chris@0: * @group simpletest Chris@0: */ Chris@0: ", Chris@0: ]; Chris@0: Chris@0: // Multiple @dependencies annotation. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: 'description' => 'Tests the Simpletest UI internal browser.', Chris@0: 'type' => 'Simpletest', Chris@0: 'requires' => ['module' => ['test', 'test1', 'test2']], Chris@0: 'group' => 'simpletest', Chris@18: 'groups' => ['simpletest'], Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: // Doc block. Chris@0: "/** Chris@0: * Tests the Simpletest UI internal browser. Chris@0: * Chris@0: * @dependencies test, test1, test2 Chris@0: * @group simpletest Chris@0: */ Chris@0: ", Chris@0: ]; Chris@0: Chris@0: // Multi-line summary line. Chris@0: $tests[] = [ Chris@0: // Expected result. Chris@0: [ Chris@0: 'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: 'description' => 'Tests the Simpletest UI internal browser. And the summary line continues an there is no gap to the annotation.', Chris@0: 'type' => 'Simpletest', Chris@0: 'group' => 'simpletest', Chris@18: 'groups' => ['simpletest'], Chris@0: ], Chris@0: // Classname. Chris@0: 'Drupal\simpletest\Tests\ExampleSimpleTest', Chris@0: // Doc block. Chris@0: "/** Chris@0: * Tests the Simpletest UI internal browser. And the summary line continues an Chris@0: * there is no gap to the annotation. Chris@0: * Chris@0: * @group simpletest Chris@0: */ Chris@0: ", Chris@0: ]; Chris@0: return $tests; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::getTestInfo Chris@0: */ Chris@0: public function testTestInfoParserMissingGroup() { Chris@0: $classname = 'Drupal\KernelTests\field\BulkDeleteTest'; Chris@0: $doc_comment = <<setExpectedException(MissingGroupException::class, 'Missing @group annotation in Drupal\KernelTests\field\BulkDeleteTest'); Chris@0: TestDiscovery::getTestInfo($classname, $doc_comment); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::getTestInfo Chris@0: */ Chris@0: public function testTestInfoParserMissingSummary() { Chris@0: $classname = 'Drupal\KernelTests\field\BulkDeleteTest'; Chris@0: $doc_comment = <<assertEmpty($info['description']); Chris@0: } Chris@0: Chris@0: protected function setupVfsWithTestClasses() { Chris@0: vfsStream::setup('drupal'); Chris@0: Chris@0: $test_file = << [ Chris@0: 'test_module' => [ Chris@0: 'tests' => [ Chris@0: 'src' => [ Chris@0: 'Functional' => [ Chris@0: 'FunctionalExampleTest.php' => $test_file, Chris@0: 'FunctionalExampleTest2.php' => str_replace(['FunctionalExampleTest', '@group example'], ['FunctionalExampleTest2', '@group example2'], $test_file), Chris@0: ], Chris@0: 'Kernel' => [ Chris@18: 'KernelExampleTest3.php' => str_replace(['FunctionalExampleTest', '@group example'], ['KernelExampleTest3', "@group example2\n * @group kernel\n"], $test_file), Chris@17: 'KernelExampleTestBase.php' => str_replace(['FunctionalExampleTest', '@group example'], ['KernelExampleTestBase', '@group example2'], $test_file), Chris@17: 'KernelExampleTrait.php' => str_replace(['FunctionalExampleTest', '@group example'], ['KernelExampleTrait', '@group example2'], $test_file), Chris@17: 'KernelExampleInterface.php' => str_replace(['FunctionalExampleTest', '@group example'], ['KernelExampleInterface', '@group example2'], $test_file), Chris@0: ], Chris@0: ], Chris@0: ], Chris@0: ], Chris@0: ], Chris@18: 'profiles' => [ Chris@18: 'test_profile' => [ Chris@18: 'test_profile.info.yml' => $test_profile_info, Chris@18: 'modules' => [ Chris@18: 'test_profile_module' => [ Chris@18: 'test_profile_module.info.yml' => $test_module_info, Chris@18: 'tests' => [ Chris@18: 'src' => [ Chris@18: 'Kernel' => [ Chris@18: 'KernelExampleTest4.php' => str_replace(['FunctionalExampleTest', '@group example'], ['KernelExampleTest4', '@group example3'], $test_file), Chris@18: ], Chris@18: ], Chris@18: ], Chris@18: ], Chris@18: ], Chris@18: ], Chris@18: ], Chris@0: ]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::getTestClasses Chris@0: */ Chris@0: public function testGetTestClasses() { Chris@0: $this->setupVfsWithTestClasses(); Chris@0: $class_loader = $this->prophesize(ClassLoader::class); Chris@0: $module_handler = $this->prophesize(ModuleHandlerInterface::class); Chris@0: Chris@0: $test_discovery = new TestTestDiscovery('vfs://drupal', $class_loader->reveal(), $module_handler->reveal()); Chris@0: Chris@0: $extensions = [ Chris@0: 'test_module' => new Extension('vfs://drupal', 'module', 'modules/test_module/test_module.info.yml'), Chris@0: ]; Chris@0: $test_discovery->setExtensions($extensions); Chris@0: $result = $test_discovery->getTestClasses(); Chris@18: $this->assertCount(3, $result); Chris@0: $this->assertEquals([ Chris@0: 'example' => [ Chris@0: 'Drupal\Tests\test_module\Functional\FunctionalExampleTest' => [ Chris@0: 'name' => 'Drupal\Tests\test_module\Functional\FunctionalExampleTest', Chris@0: 'description' => 'Test description', Chris@0: 'group' => 'example', Chris@18: 'groups' => ['example'], Chris@0: 'type' => 'PHPUnit-Functional', Chris@0: ], Chris@0: ], Chris@0: 'example2' => [ Chris@0: 'Drupal\Tests\test_module\Functional\FunctionalExampleTest2' => [ Chris@0: 'name' => 'Drupal\Tests\test_module\Functional\FunctionalExampleTest2', Chris@0: 'description' => 'Test description', Chris@0: 'group' => 'example2', Chris@18: 'groups' => ['example2'], Chris@0: 'type' => 'PHPUnit-Functional', Chris@0: ], Chris@0: 'Drupal\Tests\test_module\Kernel\KernelExampleTest3' => [ Chris@0: 'name' => 'Drupal\Tests\test_module\Kernel\KernelExampleTest3', Chris@0: 'description' => 'Test description', Chris@0: 'group' => 'example2', Chris@18: 'groups' => ['example2', 'kernel'], Chris@18: 'type' => 'PHPUnit-Kernel', Chris@18: ], Chris@18: ], Chris@18: 'kernel' => [ Chris@18: 'Drupal\Tests\test_module\Kernel\KernelExampleTest3' => [ Chris@18: 'name' => 'Drupal\Tests\test_module\Kernel\KernelExampleTest3', Chris@18: 'description' => 'Test description', Chris@18: 'group' => 'example2', Chris@18: 'groups' => ['example2', 'kernel'], Chris@0: 'type' => 'PHPUnit-Kernel', Chris@0: ], Chris@0: ], Chris@0: ], $result); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @covers ::getTestClasses Chris@0: */ Chris@0: public function testGetTestClassesWithSelectedTypes() { Chris@0: $this->setupVfsWithTestClasses(); Chris@0: $class_loader = $this->prophesize(ClassLoader::class); Chris@0: $module_handler = $this->prophesize(ModuleHandlerInterface::class); Chris@0: Chris@0: $test_discovery = new TestTestDiscovery('vfs://drupal', $class_loader->reveal(), $module_handler->reveal()); Chris@0: Chris@0: $extensions = [ Chris@0: 'test_module' => new Extension('vfs://drupal', 'module', 'modules/test_module/test_module.info.yml'), Chris@18: 'test_profile_module' => new Extension('vfs://drupal', 'profile', 'profiles/test_profile/modules/test_profile_module/test_profile_module.info.yml'), Chris@0: ]; Chris@0: $test_discovery->setExtensions($extensions); Chris@0: $result = $test_discovery->getTestClasses(NULL, ['PHPUnit-Kernel']); Chris@18: $this->assertCount(4, $result); Chris@0: $this->assertEquals([ Chris@0: 'example' => [], Chris@0: 'example2' => [ Chris@0: 'Drupal\Tests\test_module\Kernel\KernelExampleTest3' => [ Chris@0: 'name' => 'Drupal\Tests\test_module\Kernel\KernelExampleTest3', Chris@0: 'description' => 'Test description', Chris@0: 'group' => 'example2', Chris@18: 'groups' => ['example2', 'kernel'], Chris@18: 'type' => 'PHPUnit-Kernel', Chris@18: ], Chris@18: ], Chris@18: 'kernel' => [ Chris@18: 'Drupal\Tests\test_module\Kernel\KernelExampleTest3' => [ Chris@18: 'name' => 'Drupal\Tests\test_module\Kernel\KernelExampleTest3', Chris@18: 'description' => 'Test description', Chris@18: 'group' => 'example2', Chris@18: 'groups' => ['example2', 'kernel'], Chris@18: 'type' => 'PHPUnit-Kernel', Chris@18: ], Chris@18: ], Chris@18: 'example3' => [ Chris@18: 'Drupal\Tests\test_profile_module\Kernel\KernelExampleTest4' => [ Chris@18: 'name' => 'Drupal\Tests\test_profile_module\Kernel\KernelExampleTest4', Chris@18: 'description' => 'Test description', Chris@18: 'group' => 'example3', Chris@18: 'groups' => ['example3'], Chris@0: 'type' => 'PHPUnit-Kernel', Chris@0: ], Chris@0: ], Chris@0: ], $result); Chris@0: } Chris@0: Chris@0: /** Chris@18: * @covers ::getTestClasses Chris@18: */ Chris@18: public function testGetTestsInProfiles() { Chris@18: $this->setupVfsWithTestClasses(); Chris@18: $class_loader = $this->prophesize(ClassLoader::class); Chris@18: $module_handler = $this->prophesize(ModuleHandlerInterface::class); Chris@18: Chris@18: $container = new Container(); Chris@18: $container->set('kernel', new DrupalKernel('prod', new ClassLoader())); Chris@18: $container->set('site.path', 'sites/default'); Chris@18: \Drupal::setContainer($container); Chris@18: Chris@18: $test_discovery = new TestDiscovery('vfs://drupal', $class_loader->reveal(), $module_handler->reveal()); Chris@18: Chris@18: $result = $test_discovery->getTestClasses(NULL, ['PHPUnit-Kernel']); Chris@18: $expected = [ Chris@18: 'example3' => [ Chris@18: 'Drupal\Tests\test_profile_module\Kernel\KernelExampleTest4' => [ Chris@18: 'name' => 'Drupal\Tests\test_profile_module\Kernel\KernelExampleTest4', Chris@18: 'description' => 'Test description', Chris@18: 'group' => 'example3', Chris@18: 'groups' => ['example3'], Chris@18: 'type' => 'PHPUnit-Kernel', Chris@18: ], Chris@18: ], Chris@18: ]; Chris@18: $this->assertEquals($expected, $result); Chris@18: } Chris@18: Chris@18: /** Chris@0: * @covers ::getPhpunitTestSuite Chris@0: * @dataProvider providerTestGetPhpunitTestSuite Chris@0: */ Chris@0: public function testGetPhpunitTestSuite($classname, $expected) { Chris@0: $this->assertEquals($expected, TestDiscovery::getPhpunitTestSuite($classname)); Chris@0: } Chris@0: Chris@0: public function providerTestGetPhpunitTestSuite() { Chris@0: $data = []; Chris@0: $data['simpletest-webtest'] = ['\Drupal\rest\Tests\NodeTest', FALSE]; Chris@0: $data['simpletest-kerneltest'] = ['\Drupal\hal\Tests\FileNormalizeTest', FALSE]; Chris@0: $data['module-unittest'] = [static::class, 'Unit']; Chris@0: $data['module-kerneltest'] = ['\Drupal\KernelTests\Core\Theme\TwigMarkupInterfaceTest', 'Kernel']; Chris@0: $data['module-functionaltest'] = ['\Drupal\FunctionalTests\BrowserTestBaseTest', 'Functional']; Chris@0: $data['module-functionaljavascripttest'] = ['\Drupal\Tests\toolbar\FunctionalJavascript\ToolbarIntegrationTest', 'FunctionalJavascript']; Chris@0: $data['core-unittest'] = ['\Drupal\Tests\ComposerIntegrationTest', 'Unit']; Chris@0: $data['core-unittest2'] = ['Drupal\Tests\Core\DrupalTest', 'Unit']; Chris@0: $data['core-kerneltest'] = ['\Drupal\KernelTests\KernelTestBaseTest', 'Kernel']; Chris@0: $data['core-functionaltest'] = ['\Drupal\FunctionalTests\ExampleTest', 'Functional']; Chris@0: $data['core-functionaljavascripttest'] = ['\Drupal\FunctionalJavascriptTests\ExampleTest', 'FunctionalJavascript']; Chris@0: Chris@0: return $data; Chris@0: } Chris@0: Chris@16: /** Chris@16: * Ensure that classes are not reflected when the docblock is empty. Chris@16: * Chris@16: * @covers ::getTestInfo Chris@16: */ Chris@16: public function testGetTestInfoEmptyDocblock() { Chris@16: // If getTestInfo() performed reflection, it won't be able to find the Chris@16: // class we asked it to analyze, so it will throw a ReflectionException. Chris@16: // We want to make sure it didn't do that, because we already did some Chris@16: // analysis and already have an empty docblock. getTestInfo() will throw Chris@16: // MissingGroupException because the annotation is empty. Chris@16: $this->setExpectedException(MissingGroupException::class); Chris@16: TestDiscovery::getTestInfo('Drupal\Tests\simpletest\ThisTestDoesNotExistTest', ''); Chris@16: } Chris@16: Chris@17: /** Chris@17: * Ensure TestDiscovery::scanDirectory() ignores certain abstract file types. Chris@17: * Chris@17: * @covers ::scanDirectory Chris@17: */ Chris@17: public function testScanDirectoryNoAbstract() { Chris@17: $this->setupVfsWithTestClasses(); Chris@17: $files = TestDiscovery::scanDirectory('Drupal\\Tests\\test_module\\Kernel\\', vfsStream::url('drupal/modules/test_module/tests/src/Kernel')); Chris@17: $this->assertNotEmpty($files); Chris@17: $this->assertArrayNotHasKey('Drupal\Tests\test_module\Kernel\KernelExampleTestBase', $files); Chris@17: $this->assertArrayNotHasKey('Drupal\Tests\test_module\Kernel\KernelExampleTrait', $files); Chris@17: $this->assertArrayNotHasKey('Drupal\Tests\test_module\Kernel\KernelExampleInterface', $files); Chris@17: $this->assertArrayHasKey('Drupal\Tests\test_module\Kernel\KernelExampleTest3', $files); Chris@17: } Chris@17: Chris@0: } Chris@0: Chris@0: class TestTestDiscovery extends TestDiscovery { Chris@0: Chris@0: /** Chris@0: * @var \Drupal\Core\Extension\Extension[] Chris@0: */ Chris@0: protected $extensions = []; Chris@0: Chris@0: public function setExtensions(array $extensions) { Chris@0: $this->extensions = $extensions; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function getExtensions() { Chris@0: return $this->extensions; Chris@0: } Chris@0: Chris@0: }