Yaffs site version 1.1
[yaffs-website] / vendor / drupal / console / src / Command / Test / RunCommand.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Console\Command\Test\DebugCommand.
6  */
7
8 namespace Drupal\Console\Command\Test;
9
10 use Symfony\Component\Console\Input\InputArgument;
11 use Symfony\Component\Console\Input\InputOption;
12 use Symfony\Component\Console\Input\InputInterface;
13 use Symfony\Component\Console\Output\OutputInterface;
14 use Drupal\Component\Utility\Timer;
15 use Symfony\Component\Console\Command\Command;
16 use Drupal\Console\Core\Command\Shared\CommandTrait;
17 use Drupal\Console\Annotations\DrupalCommand;
18 use Drupal\Console\Core\Style\DrupalStyle;
19 use Drupal\Core\Extension\ModuleHandlerInterface;
20 use Drupal\simpletest\TestDiscovery;
21 use Drupal\Core\Datetime\DateFormatter;
22
23 /**
24  * @DrupalCommand(
25  *     extension = "simpletest",
26  *     extensionType = "module",
27  * )
28  */
29 class RunCommand extends Command
30 {
31     use CommandTrait;
32
33     /**
34      * @var string
35      */
36     protected $appRoot;
37
38     /**
39       * @var TestDiscovery
40       */
41     protected $test_discovery;
42
43
44     /**
45      * @var ModuleHandlerInterface
46      */
47     protected $moduleHandler;
48
49
50     /**
51      * @var DateFormatter
52      */
53     protected $dateFormatter;
54
55
56
57     /**
58      * RunCommand constructor.
59      *
60      * @param Site                   $site
61      * @param TestDiscovery          $test_discovery
62      * @param ModuleHandlerInterface $moduleHandler
63      */
64     public function __construct(
65         $appRoot,
66         TestDiscovery $test_discovery,
67         ModuleHandlerInterface $moduleHandler,
68         DateFormatter $dateFormatter
69     ) {
70         $this->appRoot = $appRoot;
71         $this->test_discovery = $test_discovery;
72         $this->moduleHandler = $moduleHandler;
73         $this->dateFormatter = $dateFormatter;
74         parent::__construct();
75     }
76
77     protected function configure()
78     {
79         $this
80             ->setName('test:run')
81             ->setDescription($this->trans('commands.test.run.description'))
82             ->addArgument(
83                 'test-class',
84                 InputArgument::REQUIRED,
85                 $this->trans('commands.test.run.arguments.test-class')
86             )
87             ->addArgument(
88                 'test-methods',
89                 InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
90                 $this->trans('commands.test.run.arguments.test-methods')
91             )
92             ->addOption(
93                 'url',
94                 null,
95                 InputOption::VALUE_REQUIRED,
96                 $this->trans('commands.test.run.arguments.url')
97             );
98     }
99
100     /*
101      * Set Server variable to be used in test cases.
102      */
103
104     /**
105      * {@inheritdoc}
106      */
107     protected function execute(InputInterface $input, OutputInterface $output)
108     {
109         $io = new DrupalStyle($input, $output);
110
111         //Registers namespaces for disabled modules.
112         $this->test_discovery->registerTestNamespaces();
113
114         $testClass = $input->getArgument('test-class');
115         $testMethods = $input->getArgument('test-methods');
116
117         $url = $input->getOption('url');
118
119         if (!$url) {
120             $io->error($this->trans('commands.test.run.messages.url-required'));
121             return null;
122         }
123
124         $this->setEnvironment($url);
125
126         // Create simpletest test id
127         $testId = db_insert('simpletest_test_id')
128           ->useDefaults(['test_id'])
129           ->execute();
130
131         if (is_subclass_of($testClass, 'PHPUnit_Framework_TestCase')) {
132             $io->info($this->trans('commands.test.run.messages.phpunit-pending'));
133             return null;
134         } else {
135             if (!class_exists($testClass)) {
136                 $io->error(
137                     sprintf(
138                         $this->trans('commands.test.run.messages.invalid-class'),
139                         $testClass
140                     )
141                 );
142
143                 return 1;
144             }
145
146             $test = new $testClass($testId);
147             $io->info($this->trans('commands.test.run.messages.starting-test'));
148             Timer::start('run-tests');
149
150             $test->run($testMethods);
151
152             $end = Timer::stop('run-tests');
153
154             $io->simple(
155                 $this->trans('commands.test.run.messages.test-duration') . ': ' .  $this->dateFormatter->formatInterval($end['time'] / 1000)
156             );
157             $io->simple(
158                 $this->trans('commands.test.run.messages.test-pass') . ': ' . $test->results['#pass']
159             );
160             $io->commentBlock(
161                 $this->trans('commands.test.run.messages.test-fail') . ': ' . $test->results['#fail']
162             );
163             $io->commentBlock(
164                 $this->trans('commands.test.run.messages.test-exception') . ': ' . $test->results['#exception']
165             );
166             $io->simple(
167                 $this->trans('commands.test.run.messages.test-debug') . ': ' . $test->results['#debug']
168             );
169
170             $this->moduleHandler->invokeAll(
171                 'test_finished',
172                 [$test->results]
173             );
174
175             $io->newLine();
176             $io->info($this->trans('commands.test.run.messages.test-summary'));
177             $io->newLine();
178
179             $currentClass = null;
180             $currentGroup = null;
181             $currentStatus = null;
182
183             $messages = $this->simpletestScriptLoadMessagesByTestIds([$testId]);
184
185             foreach ($messages as $message) {
186                 if ($currentClass === null || $currentClass != $message->test_class) {
187                     $currentClass = $message->test_class;
188                     $io->comment($message->test_class);
189                 }
190
191                 if ($currentGroup === null || $currentGroup != $message->message_group) {
192                     $currentGroup =  $message->message_group;
193                 }
194
195                 if ($currentStatus === null || $currentStatus != $message->status) {
196                     $currentStatus =  $message->status;
197                     if ($message->status == 'fail') {
198                         $io->error($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
199                         $io->newLine();
200                     } else {
201                         $io->info($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
202                         $io->newLine();
203                     }
204                 }
205
206                 $io->simple(
207                     $this->trans('commands.test.run.messages.file') . ': ' . str_replace($this->appRoot, '', $message->file)
208                 );
209                 $io->simple(
210                     $this->trans('commands.test.run.messages.method') . ': ' . $message->function
211                 );
212                 $io->simple(
213                     $this->trans('commands.test.run.messages.line') . ': ' . $message->line
214                 );
215                 $io->simple(
216                     $this->trans('commands.test.run.messages.message') . ': ' . $message->message
217                 );
218                 $io->newLine();
219             }
220             return null;
221         }
222     }
223
224     protected function setEnvironment($url)
225     {
226         $base_url = 'http://';
227         $port = '80';
228
229         $parsed_url = parse_url($url);
230         $host = $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '');
231         $path = isset($parsed_url['path']) ? rtrim(rtrim($parsed_url['path']), '/') : '';
232         $port = (isset($parsed_url['port']) ? $parsed_url['port'] : $port);
233         if ($path == '/') {
234             $path = '';
235         }
236         // If the passed URL schema is 'https' then setup the $_SERVER variables
237         // properly so that testing will run under HTTPS.
238         if ($parsed_url['scheme'] == 'https') {
239             $_SERVER['HTTPS'] = 'on';
240         }
241
242
243         if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
244             $base_url = 'https://';
245         }
246         $base_url .= $host;
247         if ($path !== '') {
248             $base_url .= $path;
249         }
250         putenv('SIMPLETEST_BASE_URL=' . $base_url);
251         $_SERVER['HTTP_HOST'] = $host;
252         $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
253         $_SERVER['SERVER_ADDR'] = '127.0.0.1';
254         $_SERVER['SERVER_PORT'] = $port;
255         $_SERVER['SERVER_SOFTWARE'] = null;
256         $_SERVER['SERVER_NAME'] = 'localhost';
257         $_SERVER['REQUEST_URI'] = $path . '/';
258         $_SERVER['REQUEST_METHOD'] = 'GET';
259         $_SERVER['SCRIPT_NAME'] = $path . '/index.php';
260         $_SERVER['SCRIPT_FILENAME'] = $path . '/index.php';
261         $_SERVER['PHP_SELF'] = $path . '/index.php';
262         $_SERVER['HTTP_USER_AGENT'] = 'Drupal Console';
263     }
264
265     /*
266      * Get Simletests log after execution
267      */
268
269     protected function simpletestScriptLoadMessagesByTestIds($test_ids)
270     {
271         $results = [];
272
273         foreach ($test_ids as $test_id) {
274             $result = \Drupal::database()->query(
275                 "SELECT * FROM {simpletest} WHERE test_id = :test_id ORDER BY test_class, message_group, status", [
276                 ':test_id' => $test_id,
277                 ]
278             )->fetchAll();
279             if ($result) {
280                 $results = array_merge($results, $result);
281             }
282         }
283
284         return $results;
285     }
286 }