diff --git a/Test/Command/GeneratorJsTestCommandTest.php b/Test/Command/GeneratorJsTestCommandTest.php new file mode 100644 index 000000000..09b0521de --- /dev/null +++ b/Test/Command/GeneratorJsTestCommandTest.php @@ -0,0 +1,55 @@ +getHelperSet()); + $command->setHelperSet($this->getHelperSet()); + $command->setGenerator($this->getGenerator()); + + $commandTester = new CommandTester($command); + + $code = $commandTester->execute( + [ + '--module' => $module, + '--class' => $class_name, + ], + ['interactive' => false] + ); + + $this->assertEquals(0, $code); + } + + private function getGenerator() + { + return $this + ->getMockBuilder('Drupal\Console\Generator\JsTestGenerator') + ->disableOriginalConstructor() + ->setMethods(['generate']) + ->getMock(); + } +} diff --git a/Test/DataProvider/JsTestDataProviderTrait.php b/Test/DataProvider/JsTestDataProviderTrait.php new file mode 100644 index 000000000..1691aafae --- /dev/null +++ b/Test/DataProvider/JsTestDataProviderTrait.php @@ -0,0 +1,22 @@ +setUpTemporaryDirectory(); + + return [ + ['foo', 'JsFooTest'], + ]; + } +} diff --git a/Test/Generator/JsTestGeneratorTest.php b/Test/Generator/JsTestGeneratorTest.php new file mode 100644 index 000000000..d7f3c5ede --- /dev/null +++ b/Test/Generator/JsTestGeneratorTest.php @@ -0,0 +1,50 @@ +getRenderHelper()->setSkeletonDirs($this->getSkeletonDirs()); + $this->getRenderHelper()->setTranslator($this->getTranslatorHelper()); + $generator->setHelperSet($this->getHelperSet()); + + $generator->generate( + $module, + $class_name + ); + + $files = [ + $generator->getSite()->getJsTestsPath($module) . "/$class_name.php", + ]; + + foreach ($files as $file) { + $this->assertTrue( + file_exists($file), + sprintf('%s does not exist', $file) + ); + } + } +} diff --git a/config/services/generate.yml b/config/services/generate.yml index 1c0452a67..65bae4f20 100644 --- a/config/services/generate.yml +++ b/config/services/generate.yml @@ -204,3 +204,8 @@ services: arguments: [ '@console.cache_context_generator', '@console.chain_queue', '@console.extension_manager', '@console.string_converter'] tags: - { name: drupal.command } + console.generate_js_test: + class: Drupal\Console\Command\Generate\JsTestCommand + arguments: ['@console.extension_manager', '@console.js_test_generator', '@console.validator'] + tags: + - { name: drupal.command } diff --git a/config/services/generator.yml b/config/services/generator.yml index d5eb5f4a5..33de8156e 100644 --- a/config/services/generator.yml +++ b/config/services/generator.yml @@ -201,3 +201,8 @@ services: arguments: ['@console.extension_manager'] tags: - { name: drupal.generator } + console.js_test_generator: + class: Drupal\Console\Generator\JsTestGenerator + arguments: ['@console.extension_manager'] + tags: + - { name: drupal.generator } diff --git a/src/Command/Generate/JsTestCommand.php b/src/Command/Generate/JsTestCommand.php new file mode 100644 index 000000000..418aa1621 --- /dev/null +++ b/src/Command/Generate/JsTestCommand.php @@ -0,0 +1,145 @@ +extensionManager = $extensionManager; + $this->generator = $generator; + $this->validator = $validator; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('generate:jstest') + ->setDescription($this->trans('commands.generate.jstest.description')) + ->setHelp($this->trans('commands.generate.jstest.help')) + ->addOption( + 'module', + null, + InputOption::VALUE_REQUIRED, + $this->trans('commands.common.options.module') + ) + ->addOption( + 'class', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.jstest.options.class') + ) + ->setAliases(['gjt']); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new DrupalStyle($input, $output); + $yes = $input->hasOption('yes') ? $input->getOption('yes') : false; + + // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration + if (!$this->confirmGeneration($io, $yes)) { + return 1; + } + + $module = $input->getOption('module'); + $class = $input->getOption('class'); + + $this->generator->generate( + $module, + $class + ); + + return 0; + } + + /** + * {@inheritdoc} + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + $io = new DrupalStyle($input, $output); + + // --module option + $module = $input->getOption('module'); + if (!$module) { + // @see Drupal\Console\Command\Shared\ModuleTrait::moduleQuestion + $module = $this->moduleQuestion($io); + $input->setOption('module', $module); + } + + // --class option + $class = $input->getOption('class'); + if (!$class) { + $class = $io->ask( + $this->trans('commands.generate.jstest.questions.class'), + 'DefaultJsTest', + function ($class) { + return $this->validator->validateClassName($class); + } + ); + $input->setOption('class', $class); + } + } + + /** + * @return \Drupal\Console\Generator\JsTestGenerator + */ + protected function createGenerator() + { + return new JsTestGenerator(); + } +} diff --git a/src/Extension/Extension.php b/src/Extension/Extension.php index 6f6c71f11..42d54ad26 100644 --- a/src/Extension/Extension.php +++ b/src/Extension/Extension.php @@ -114,4 +114,31 @@ public function getTemplatePath($fullPath = false) { return $this->getPath($fullPath) . '/templates'; } + + /** + * @param bool $fullPath + * @return string + */ + public function getTestsPath($fullPath = false) + { + return $this->getPath($fullPath) . '/tests'; + } + + /** + * @param bool $fullPath + * @return string + */ + public function getTestsSourcePath($fullPath = false) + { + return $this->getTestsPath($fullPath) . '/src'; + } + + /** + * @param bool $fullPath + * @return string + */ + public function getJsTestsPath($fullPath = false) + { + return $this->getTestsSourcePath($fullPath) . '/FunctionalJavascript'; + } } diff --git a/src/Generator/JsTestGenerator.php b/src/Generator/JsTestGenerator.php new file mode 100644 index 000000000..e5201096b --- /dev/null +++ b/src/Generator/JsTestGenerator.php @@ -0,0 +1,52 @@ +extensionManager = $extensionManager; + } + + /** + * @param $module + * @param $class + */ + public function generate($module, $class) + { + $parameters = [ + 'module' => $module, + 'class' => $class, + ]; + + $this->renderFile( + 'module/src/Tests/js-test.php.twig', + $this->extensionManager->getModule($module)->getJsTestsPath() . "/$class.php", + $parameters + ); + } +} diff --git a/templates/module/src/Tests/js-test.php.twig b/templates/module/src/Tests/js-test.php.twig new file mode 100644 index 000000000..923b8660c --- /dev/null +++ b/templates/module/src/Tests/js-test.php.twig @@ -0,0 +1,56 @@ +{% extends "base/class.php.twig" %} + +{% block file_path %} +\Drupal\Tests\{{ module }}\FunctionalJavascript\{{ class }} +{% endblock %} + +{% block namespace_class %} +namespace Drupal\Tests\{{ module }}\FunctionalJavascript; +{% endblock %} + +{% block use_class %} +use Drupal\FunctionalJavascriptTests\JavascriptTestBase; +{% endblock %} + +{% block class_declaration %} +/** + * JavaScript tests. + * + * @ingroup {{ module }} + * + * @group {{ module }} + */ +class {{ class }} extends JavaScriptTestBase {% endblock %} +{% block class_methods %} + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['{{ module }}']; + + /** + * A user with permission to administer site configuration. + * + * @var \Drupal\user\UserInterface + */ + protected $user; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->user = $this->drupalCreateUser(['administer site configuration']); + $this->drupalLogin($this->user); + } + + /** + * Tests that the home page loads with a 200 response. + */ + public function testFrontpage() { + $this->drupalGet(Url::fromRoute('')); + $page = $this->getSession()->getPage(); + $this->assertResponse(200); + } +{% endblock %}