Completed
Push — master ( 52755b...6c4366 )
by smiley
02:13
created
vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -6,8 +6,8 @@
 block discarded – undo
6 6
  */
7 7
 class OneTest extends TestCase
8 8
 {
9
-    public function testSomething()
10
-    {
11
-        $this->assertTrue(true);
12
-    }
9
+	public function testSomething()
10
+	{
11
+		$this->assertTrue(true);
12
+	}
13 13
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -6,12 +6,12 @@
 block discarded – undo
6 6
 
7 7
 class ChildSuite
8 8
 {
9
-    public static function suite()
10
-    {
11
-        $suite = new TestSuite('Child');
12
-        $suite->addTestSuite(OneTest::class);
13
-        $suite->addTestSuite(TwoTest::class);
9
+	public static function suite()
10
+	{
11
+		$suite = new TestSuite('Child');
12
+		$suite->addTestSuite(OneTest::class);
13
+		$suite->addTestSuite(TwoTest::class);
14 14
 
15
-        return $suite;
16
-    }
15
+		return $suite;
16
+	}
17 17
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/tests/Regression/Trac/783/ParentSuite.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -5,11 +5,11 @@
 block discarded – undo
5 5
 
6 6
 class ParentSuite
7 7
 {
8
-    public static function suite()
9
-    {
10
-        $suite = new TestSuite('Parent');
11
-        $suite->addTest(ChildSuite::suite());
8
+	public static function suite()
9
+	{
10
+		$suite = new TestSuite('Parent');
11
+		$suite->addTest(ChildSuite::suite());
12 12
 
13
-        return $suite;
14
-    }
13
+		return $suite;
14
+	}
15 15
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/src/Util/Test.php 1 patch
Indentation   +1151 added lines, -1151 removed lines patch added patch discarded remove patch
@@ -31,1155 +31,1155 @@
 block discarded – undo
31 31
  */
32 32
 class Test
33 33
 {
34
-    const REGEX_DATA_PROVIDER               = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/';
35
-    const REGEX_TEST_WITH                   = '/@testWith\s+/';
36
-    const REGEX_EXPECTED_EXCEPTION          = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m';
37
-    const REGEX_REQUIRES_VERSION            = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
38
-    const REGEX_REQUIRES_VERSION_CONSTRAINT = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<constraint>[\d\t -.|~^]+)[ \t]*\r?$/m';
39
-    const REGEX_REQUIRES_OS                 = '/@requires\s+(?P<name>OS(?:FAMILY)?)\s+(?P<value>.+?)[ \t]*\r?$/m';
40
-    const REGEX_REQUIRES                    = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^ ]+?))\s*(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+[\d\.]?)?[ \t]*\r?$/m';
41
-
42
-    const UNKNOWN = -1;
43
-    const SMALL   = 0;
44
-    const MEDIUM  = 1;
45
-    const LARGE   = 2;
46
-
47
-    private static $annotationCache = [];
48
-
49
-    private static $hookMethods = [];
50
-
51
-    /**
52
-     * @param \PHPUnit\Framework\Test $test
53
-     * @param bool                    $asString
54
-     *
55
-     * @return mixed
56
-     */
57
-    public static function describe(\PHPUnit\Framework\Test $test, $asString = true)
58
-    {
59
-        if ($asString) {
60
-            if ($test instanceof SelfDescribing) {
61
-                return $test->toString();
62
-            }
63
-
64
-            return \get_class($test);
65
-        }
66
-
67
-        if ($test instanceof TestCase) {
68
-            return [
69
-                \get_class($test), $test->getName()
70
-            ];
71
-        }
72
-
73
-        if ($test instanceof SelfDescribing) {
74
-            return ['', $test->toString()];
75
-        }
76
-
77
-        return ['', \get_class($test)];
78
-    }
79
-
80
-    /**
81
-     * @param string $className
82
-     * @param string $methodName
83
-     *
84
-     * @return array|bool
85
-     *
86
-     * @throws CodeCoverageException
87
-     */
88
-    public static function getLinesToBeCovered($className, $methodName)
89
-    {
90
-        $annotations = self::parseTestMethodAnnotations(
91
-            $className,
92
-            $methodName
93
-        );
94
-
95
-        if (isset($annotations['class']['coversNothing']) || isset($annotations['method']['coversNothing'])) {
96
-            return false;
97
-        }
98
-
99
-        return self::getLinesToBeCoveredOrUsed($className, $methodName, 'covers');
100
-    }
101
-
102
-    /**
103
-     * Returns lines of code specified with the @uses annotation.
104
-     *
105
-     * @param string $className
106
-     * @param string $methodName
107
-     *
108
-     * @return array
109
-     */
110
-    public static function getLinesToBeUsed($className, $methodName)
111
-    {
112
-        return self::getLinesToBeCoveredOrUsed($className, $methodName, 'uses');
113
-    }
114
-
115
-    /**
116
-     * @param string $className
117
-     * @param string $methodName
118
-     * @param string $mode
119
-     *
120
-     * @return array
121
-     *
122
-     * @throws CodeCoverageException
123
-     */
124
-    private static function getLinesToBeCoveredOrUsed($className, $methodName, $mode)
125
-    {
126
-        $annotations = self::parseTestMethodAnnotations(
127
-            $className,
128
-            $methodName
129
-        );
130
-
131
-        $classShortcut = null;
132
-
133
-        if (!empty($annotations['class'][$mode . 'DefaultClass'])) {
134
-            if (\count($annotations['class'][$mode . 'DefaultClass']) > 1) {
135
-                throw new CodeCoverageException(
136
-                    \sprintf(
137
-                        'More than one @%sClass annotation in class or interface "%s".',
138
-                        $mode,
139
-                        $className
140
-                    )
141
-                );
142
-            }
143
-
144
-            $classShortcut = $annotations['class'][$mode . 'DefaultClass'][0];
145
-        }
146
-
147
-        $list = [];
148
-
149
-        if (isset($annotations['class'][$mode])) {
150
-            $list = $annotations['class'][$mode];
151
-        }
152
-
153
-        if (isset($annotations['method'][$mode])) {
154
-            $list = \array_merge($list, $annotations['method'][$mode]);
155
-        }
156
-
157
-        $codeList = [];
158
-
159
-        foreach (\array_unique($list) as $element) {
160
-            if ($classShortcut && \strncmp($element, '::', 2) === 0) {
161
-                $element = $classShortcut . $element;
162
-            }
163
-
164
-            $element = \preg_replace('/[\s()]+$/', '', $element);
165
-            $element = \explode(' ', $element);
166
-            $element = $element[0];
167
-
168
-            $codeList = \array_merge(
169
-                $codeList,
170
-                self::resolveElementToReflectionObjects($element)
171
-            );
172
-        }
173
-
174
-        return self::resolveReflectionObjectsToLines($codeList);
175
-    }
176
-
177
-    /**
178
-     * Returns the requirements for a test.
179
-     *
180
-     * @param string $className
181
-     * @param string $methodName
182
-     *
183
-     * @return array
184
-     */
185
-    public static function getRequirements($className, $methodName)
186
-    {
187
-        $reflector  = new ReflectionClass($className);
188
-        $docComment = $reflector->getDocComment();
189
-        $reflector  = new ReflectionMethod($className, $methodName);
190
-        $docComment .= "\n" . $reflector->getDocComment();
191
-        $requires = [];
192
-
193
-        if ($count = \preg_match_all(self::REGEX_REQUIRES_OS, $docComment, $matches)) {
194
-            foreach (\range(0, $count - 1) as $i) {
195
-                $requires[$matches['name'][$i]] = $matches['value'][$i];
196
-            }
197
-        }
198
-
199
-        if ($count = \preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) {
200
-            foreach (\range(0, $count - 1) as $i) {
201
-                $requires[$matches['name'][$i]] = [
202
-                    'version'  => $matches['version'][$i],
203
-                    'operator' => $matches['operator'][$i]
204
-                ];
205
-            }
206
-        }
207
-        if ($count = \preg_match_all(self::REGEX_REQUIRES_VERSION_CONSTRAINT, $docComment, $matches)) {
208
-            foreach (\range(0, $count - 1) as $i) {
209
-                if (!empty($requires[$matches['name'][$i]])) {
210
-                    continue;
211
-                }
212
-
213
-                try {
214
-                    $versionConstraintParser = new VersionConstraintParser;
215
-
216
-                    $requires[$matches['name'][$i] . '_constraint'] = [
217
-                        'constraint' => $versionConstraintParser->parse(\trim($matches['constraint'][$i]))
218
-                    ];
219
-                } catch (\PharIo\Version\Exception $e) {
220
-                    throw new Warning($e->getMessage(), $e->getCode(), $e);
221
-                }
222
-            }
223
-        }
224
-
225
-        if ($count = \preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) {
226
-            foreach (\range(0, $count - 1) as $i) {
227
-                $name = $matches['name'][$i] . 's';
228
-
229
-                if (!isset($requires[$name])) {
230
-                    $requires[$name] = [];
231
-                }
232
-
233
-                $requires[$name][] = $matches['value'][$i];
234
-
235
-                if (empty($matches['version'][$i]) || $name != 'extensions') {
236
-                    continue;
237
-                }
238
-
239
-                $requires['extension_versions'][$matches['value'][$i]] = [
240
-                    'version'  => $matches['version'][$i],
241
-                    'operator' => $matches['operator'][$i]
242
-                ];
243
-            }
244
-        }
245
-
246
-        return $requires;
247
-    }
248
-
249
-    /**
250
-     * Returns the missing requirements for a test.
251
-     *
252
-     * @param string $className
253
-     * @param string $methodName
254
-     *
255
-     * @return string[]
256
-     */
257
-    public static function getMissingRequirements($className, $methodName)
258
-    {
259
-        $required = static::getRequirements($className, $methodName);
260
-        $missing  = [];
261
-
262
-        if (!empty($required['PHP'])) {
263
-            $operator = empty($required['PHP']['operator']) ? '>=' : $required['PHP']['operator'];
264
-
265
-            if (!\version_compare(PHP_VERSION, $required['PHP']['version'], $operator)) {
266
-                $missing[] = \sprintf('PHP %s %s is required.', $operator, $required['PHP']['version']);
267
-            }
268
-        } elseif (!empty($required['PHP_constraint'])) {
269
-            $version = new \PharIo\Version\Version(self::sanitizeVersionNumber(PHP_VERSION));
270
-
271
-            if (!$required['PHP_constraint']['constraint']->complies($version)) {
272
-                $missing[] = \sprintf(
273
-                    'PHP version does not match the required constraint %s.',
274
-                    $required['PHP_constraint']['constraint']->asString()
275
-                );
276
-            }
277
-        }
278
-
279
-        if (!empty($required['PHPUnit'])) {
280
-            $phpunitVersion = Version::id();
281
-
282
-            $operator = empty($required['PHPUnit']['operator']) ? '>=' : $required['PHPUnit']['operator'];
283
-
284
-            if (!\version_compare($phpunitVersion, $required['PHPUnit']['version'], $operator)) {
285
-                $missing[] = \sprintf('PHPUnit %s %s is required.', $operator, $required['PHPUnit']['version']);
286
-            }
287
-        } elseif (!empty($required['PHPUnit_constraint'])) {
288
-            $phpunitVersion = new \PharIo\Version\Version(self::sanitizeVersionNumber(Version::id()));
289
-
290
-            if (!$required['PHPUnit_constraint']['constraint']->complies($phpunitVersion)) {
291
-                $missing[] = \sprintf(
292
-                    'PHPUnit version does not match the required constraint %s.',
293
-                    $required['PHPUnit_constraint']['constraint']->asString()
294
-                );
295
-            }
296
-        }
297
-
298
-        if (!empty($required['OSFAMILY']) && $required['OSFAMILY'] !== (new OperatingSystem())->getFamily()) {
299
-            $missing[] = \sprintf('Operating system %s is required.', $required['OSFAMILY']);
300
-        }
301
-
302
-        if (!empty($required['OS'])) {
303
-            $requiredOsPattern = \sprintf('/%s/i', \addcslashes($required['OS'], '/'));
304
-            if (!\preg_match($requiredOsPattern, PHP_OS)) {
305
-                $missing[] = \sprintf('Operating system matching %s is required.', $requiredOsPattern);
306
-            }
307
-        }
308
-
309
-        if (!empty($required['functions'])) {
310
-            foreach ($required['functions'] as $function) {
311
-                $pieces = \explode('::', $function);
312
-
313
-                if (2 === \count($pieces) && \method_exists($pieces[0], $pieces[1])) {
314
-                    continue;
315
-                }
316
-
317
-                if (\function_exists($function)) {
318
-                    continue;
319
-                }
320
-
321
-                $missing[] = \sprintf('Function %s is required.', $function);
322
-            }
323
-        }
324
-
325
-        if (!empty($required['extensions'])) {
326
-            foreach ($required['extensions'] as $extension) {
327
-                if (isset($required['extension_versions'][$extension])) {
328
-                    continue;
329
-                }
330
-
331
-                if (!\extension_loaded($extension)) {
332
-                    $missing[] = \sprintf('Extension %s is required.', $extension);
333
-                }
334
-            }
335
-        }
336
-
337
-        if (!empty($required['extension_versions'])) {
338
-            foreach ($required['extension_versions'] as $extension => $required) {
339
-                $actualVersion = \phpversion($extension);
340
-
341
-                $operator = empty($required['operator']) ? '>=' : $required['operator'];
342
-
343
-                if (false === $actualVersion || !\version_compare($actualVersion, $required['version'], $operator)) {
344
-                    $missing[] = \sprintf('Extension %s %s %s is required.', $extension, $operator, $required['version']);
345
-                }
346
-            }
347
-        }
348
-
349
-        return $missing;
350
-    }
351
-
352
-    /**
353
-     * Returns the expected exception for a test.
354
-     *
355
-     * @param string $className
356
-     * @param string $methodName
357
-     *
358
-     * @return array|false
359
-     */
360
-    public static function getExpectedException($className, $methodName)
361
-    {
362
-        $reflector  = new ReflectionMethod($className, $methodName);
363
-        $docComment = $reflector->getDocComment();
364
-        $docComment = \substr($docComment, 3, -2);
365
-
366
-        if (\preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) {
367
-            $annotations = self::parseTestMethodAnnotations(
368
-                $className,
369
-                $methodName
370
-            );
371
-
372
-            $class         = $matches[1];
373
-            $code          = null;
374
-            $message       = '';
375
-            $messageRegExp = '';
376
-
377
-            if (isset($matches[2])) {
378
-                $message = \trim($matches[2]);
379
-            } elseif (isset($annotations['method']['expectedExceptionMessage'])) {
380
-                $message = self::parseAnnotationContent(
381
-                    $annotations['method']['expectedExceptionMessage'][0]
382
-                );
383
-            }
384
-
385
-            if (isset($annotations['method']['expectedExceptionMessageRegExp'])) {
386
-                $messageRegExp = self::parseAnnotationContent(
387
-                    $annotations['method']['expectedExceptionMessageRegExp'][0]
388
-                );
389
-            }
390
-
391
-            if (isset($matches[3])) {
392
-                $code = $matches[3];
393
-            } elseif (isset($annotations['method']['expectedExceptionCode'])) {
394
-                $code = self::parseAnnotationContent(
395
-                    $annotations['method']['expectedExceptionCode'][0]
396
-                );
397
-            }
398
-
399
-            if (\is_numeric($code)) {
400
-                $code = (int) $code;
401
-            } elseif (\is_string($code) && \defined($code)) {
402
-                $code = (int) \constant($code);
403
-            }
404
-
405
-            return [
406
-                'class' => $class, 'code' => $code, 'message' => $message, 'message_regex' => $messageRegExp
407
-            ];
408
-        }
409
-
410
-        return false;
411
-    }
412
-
413
-    /**
414
-     * Parse annotation content to use constant/class constant values
415
-     *
416
-     * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME
417
-     *
418
-     * If the constant is not found the string is used as is to ensure maximum BC.
419
-     *
420
-     * @param string $message
421
-     *
422
-     * @return string
423
-     */
424
-    private static function parseAnnotationContent($message)
425
-    {
426
-        if ((\strpos($message, '::') !== false && \count(\explode('::', $message)) == 2) && \defined($message)) {
427
-            $message = \constant($message);
428
-        }
429
-
430
-        return $message;
431
-    }
432
-
433
-    /**
434
-     * Returns the provided data for a method.
435
-     *
436
-     * @param string $className
437
-     * @param string $methodName
438
-     *
439
-     * @return array When a data provider is specified and exists
440
-     *               null  When no data provider is specified
441
-     *
442
-     * @throws Exception
443
-     */
444
-    public static function getProvidedData($className, $methodName)
445
-    {
446
-        $reflector  = new ReflectionMethod($className, $methodName);
447
-        $docComment = $reflector->getDocComment();
448
-
449
-        $data = self::getDataFromDataProviderAnnotation($docComment, $className, $methodName);
450
-
451
-        if ($data === null) {
452
-            $data = self::getDataFromTestWithAnnotation($docComment);
453
-        }
454
-
455
-        if (\is_array($data) && empty($data)) {
456
-            throw new SkippedTestError;
457
-        }
458
-
459
-        if ($data !== null) {
460
-            foreach ($data as $key => $value) {
461
-                if (!\is_array($value)) {
462
-                    throw new Exception(
463
-                        \sprintf(
464
-                            'Data set %s is invalid.',
465
-                            \is_int($key) ? '#' . $key : '"' . $key . '"'
466
-                        )
467
-                    );
468
-                }
469
-            }
470
-        }
471
-
472
-        return $data;
473
-    }
474
-
475
-    /**
476
-     * Returns the provided data for a method.
477
-     *
478
-     * @param string $docComment
479
-     * @param string $className
480
-     * @param string $methodName
481
-     *
482
-     * @return array|Iterator when a data provider is specified and exists
483
-     *                        null           when no data provider is specified
484
-     *
485
-     * @throws Exception
486
-     */
487
-    private static function getDataFromDataProviderAnnotation($docComment, $className, $methodName)
488
-    {
489
-        if (\preg_match_all(self::REGEX_DATA_PROVIDER, $docComment, $matches)) {
490
-            $result = [];
491
-
492
-            foreach ($matches[1] as $match) {
493
-                $dataProviderMethodNameNamespace = \explode('\\', $match);
494
-                $leaf                            = \explode('::', \array_pop($dataProviderMethodNameNamespace));
495
-                $dataProviderMethodName          = \array_pop($leaf);
496
-
497
-                if (!empty($dataProviderMethodNameNamespace)) {
498
-                    $dataProviderMethodNameNamespace = \implode('\\', $dataProviderMethodNameNamespace) . '\\';
499
-                } else {
500
-                    $dataProviderMethodNameNamespace = '';
501
-                }
502
-
503
-                if (!empty($leaf)) {
504
-                    $dataProviderClassName = $dataProviderMethodNameNamespace . \array_pop($leaf);
505
-                } else {
506
-                    $dataProviderClassName = $className;
507
-                }
508
-
509
-                $dataProviderClass  = new ReflectionClass($dataProviderClassName);
510
-                $dataProviderMethod = $dataProviderClass->getMethod(
511
-                    $dataProviderMethodName
512
-                );
513
-
514
-                if ($dataProviderMethod->isStatic()) {
515
-                    $object = null;
516
-                } else {
517
-                    $object = $dataProviderClass->newInstance();
518
-                }
519
-
520
-                if ($dataProviderMethod->getNumberOfParameters() == 0) {
521
-                    $data = $dataProviderMethod->invoke($object);
522
-                } else {
523
-                    $data = $dataProviderMethod->invoke($object, $methodName);
524
-                }
525
-
526
-                if ($data instanceof Traversable) {
527
-                    $data = \iterator_to_array($data, false);
528
-                }
529
-
530
-                if (\is_array($data)) {
531
-                    $result = \array_merge($result, $data);
532
-                }
533
-            }
534
-
535
-            return $result;
536
-        }
537
-    }
538
-
539
-    /**
540
-     * @param string $docComment full docComment string
541
-     *
542
-     * @return array|null array when @testWith annotation is defined,
543
-     *                    null when @testWith annotation is omitted
544
-     *
545
-     * @throws Exception when @testWith annotation is defined but cannot be parsed
546
-     */
547
-    public static function getDataFromTestWithAnnotation($docComment)
548
-    {
549
-        $docComment = self::cleanUpMultiLineAnnotation($docComment);
550
-
551
-        if (\preg_match(self::REGEX_TEST_WITH, $docComment, $matches, PREG_OFFSET_CAPTURE)) {
552
-            $offset            = \strlen($matches[0][0]) + $matches[0][1];
553
-            $annotationContent = \substr($docComment, $offset);
554
-            $data              = [];
555
-
556
-            foreach (\explode("\n", $annotationContent) as $candidateRow) {
557
-                $candidateRow = \trim($candidateRow);
558
-
559
-                if ($candidateRow[0] !== '[') {
560
-                    break;
561
-                }
562
-
563
-                $dataSet = \json_decode($candidateRow, true);
564
-
565
-                if (\json_last_error() != JSON_ERROR_NONE) {
566
-                    throw new Exception(
567
-                        'The dataset for the @testWith annotation cannot be parsed: ' . \json_last_error_msg()
568
-                    );
569
-                }
570
-
571
-                $data[] = $dataSet;
572
-            }
573
-
574
-            if (!$data) {
575
-                throw new Exception('The dataset for the @testWith annotation cannot be parsed.');
576
-            }
577
-
578
-            return $data;
579
-        }
580
-    }
581
-
582
-    private static function cleanUpMultiLineAnnotation($docComment)
583
-    {
584
-        //removing initial '   * ' for docComment
585
-        $docComment = \str_replace("\r\n", "\n", $docComment);
586
-        $docComment = \preg_replace('/' . '\n' . '\s*' . '\*' . '\s?' . '/', "\n", $docComment);
587
-        $docComment = \substr($docComment, 0, -1);
588
-        $docComment = \rtrim($docComment, "\n");
589
-
590
-        return $docComment;
591
-    }
592
-
593
-    /**
594
-     * @param string $className
595
-     * @param string $methodName
596
-     *
597
-     * @return array
598
-     *
599
-     * @throws ReflectionException
600
-     */
601
-    public static function parseTestMethodAnnotations($className, $methodName = '')
602
-    {
603
-        if (!isset(self::$annotationCache[$className])) {
604
-            $class       = new ReflectionClass($className);
605
-            $traits      = $class->getTraits();
606
-            $annotations = [];
607
-
608
-            foreach ($traits as $trait) {
609
-                $annotations = \array_merge(
610
-                    $annotations,
611
-                    self::parseAnnotations($trait->getDocComment())
612
-                );
613
-            }
614
-
615
-            self::$annotationCache[$className] = \array_merge(
616
-                $annotations,
617
-                self::parseAnnotations($class->getDocComment())
618
-            );
619
-        }
620
-
621
-        if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) {
622
-            try {
623
-                $method      = new ReflectionMethod($className, $methodName);
624
-                $annotations = self::parseAnnotations($method->getDocComment());
625
-            } catch (ReflectionException $e) {
626
-                $annotations = [];
627
-            }
628
-
629
-            self::$annotationCache[$className . '::' . $methodName] = $annotations;
630
-        }
631
-
632
-        return [
633
-            'class'  => self::$annotationCache[$className],
634
-            'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : []
635
-        ];
636
-    }
637
-
638
-    /**
639
-     * @param string $className
640
-     * @param string $methodName
641
-     *
642
-     * @return array
643
-     */
644
-    public static function getInlineAnnotations($className, $methodName)
645
-    {
646
-        $method      = new ReflectionMethod($className, $methodName);
647
-        $code        = \file($method->getFileName());
648
-        $lineNumber  = $method->getStartLine();
649
-        $startLine   = $method->getStartLine() - 1;
650
-        $endLine     = $method->getEndLine() - 1;
651
-        $methodLines = \array_slice($code, $startLine, $endLine - $startLine + 1);
652
-        $annotations = [];
653
-
654
-        foreach ($methodLines as $line) {
655
-            if (\preg_match('#/\*\*?\s*@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?\*/$#m', $line, $matches)) {
656
-                $annotations[\strtolower($matches['name'])] = [
657
-                    'line'  => $lineNumber,
658
-                    'value' => $matches['value']
659
-                ];
660
-            }
661
-
662
-            $lineNumber++;
663
-        }
664
-
665
-        return $annotations;
666
-    }
667
-
668
-    /**
669
-     * @param string $docblock
670
-     *
671
-     * @return array
672
-     */
673
-    private static function parseAnnotations($docblock)
674
-    {
675
-        $annotations = [];
676
-        // Strip away the docblock header and footer to ease parsing of one line annotations
677
-        $docblock = \substr($docblock, 3, -2);
678
-
679
-        if (\preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docblock, $matches)) {
680
-            $numMatches = \count($matches[0]);
681
-
682
-            for ($i = 0; $i < $numMatches; ++$i) {
683
-                $annotations[$matches['name'][$i]][] = (string) $matches['value'][$i];
684
-            }
685
-        }
686
-
687
-        return $annotations;
688
-    }
689
-
690
-    /**
691
-     * Returns the backup settings for a test.
692
-     *
693
-     * @param string $className
694
-     * @param string $methodName
695
-     *
696
-     * @return array<string, bool|null>
697
-     */
698
-    public static function getBackupSettings($className, $methodName)
699
-    {
700
-        return [
701
-            'backupGlobals' => self::getBooleanAnnotationSetting(
702
-                $className,
703
-                $methodName,
704
-                'backupGlobals'
705
-            ),
706
-            'backupStaticAttributes' => self::getBooleanAnnotationSetting(
707
-                $className,
708
-                $methodName,
709
-                'backupStaticAttributes'
710
-            )
711
-        ];
712
-    }
713
-
714
-    /**
715
-     * Returns the dependencies for a test class or method.
716
-     *
717
-     * @param string $className
718
-     * @param string $methodName
719
-     *
720
-     * @return array
721
-     */
722
-    public static function getDependencies($className, $methodName)
723
-    {
724
-        $annotations = self::parseTestMethodAnnotations(
725
-            $className,
726
-            $methodName
727
-        );
728
-
729
-        $dependencies = [];
730
-
731
-        if (isset($annotations['class']['depends'])) {
732
-            $dependencies = $annotations['class']['depends'];
733
-        }
734
-
735
-        if (isset($annotations['method']['depends'])) {
736
-            $dependencies = \array_merge(
737
-                $dependencies,
738
-                $annotations['method']['depends']
739
-            );
740
-        }
741
-
742
-        return \array_unique($dependencies);
743
-    }
744
-
745
-    /**
746
-     * Returns the error handler settings for a test.
747
-     *
748
-     * @param string $className
749
-     * @param string $methodName
750
-     *
751
-     * @return ?bool
752
-     */
753
-    public static function getErrorHandlerSettings($className, $methodName)
754
-    {
755
-        return self::getBooleanAnnotationSetting(
756
-            $className,
757
-            $methodName,
758
-            'errorHandler'
759
-        );
760
-    }
761
-
762
-    /**
763
-     * Returns the groups for a test class or method.
764
-     *
765
-     * @param string $className
766
-     * @param string $methodName
767
-     *
768
-     * @return array
769
-     */
770
-    public static function getGroups($className, $methodName = '')
771
-    {
772
-        $annotations = self::parseTestMethodAnnotations(
773
-            $className,
774
-            $methodName
775
-        );
776
-
777
-        $groups = [];
778
-
779
-        if (isset($annotations['method']['author'])) {
780
-            $groups = $annotations['method']['author'];
781
-        } elseif (isset($annotations['class']['author'])) {
782
-            $groups = $annotations['class']['author'];
783
-        }
784
-
785
-        if (isset($annotations['class']['group'])) {
786
-            $groups = \array_merge($groups, $annotations['class']['group']);
787
-        }
788
-
789
-        if (isset($annotations['method']['group'])) {
790
-            $groups = \array_merge($groups, $annotations['method']['group']);
791
-        }
792
-
793
-        if (isset($annotations['class']['ticket'])) {
794
-            $groups = \array_merge($groups, $annotations['class']['ticket']);
795
-        }
796
-
797
-        if (isset($annotations['method']['ticket'])) {
798
-            $groups = \array_merge($groups, $annotations['method']['ticket']);
799
-        }
800
-
801
-        foreach (['method', 'class'] as $element) {
802
-            foreach (['small', 'medium', 'large'] as $size) {
803
-                if (isset($annotations[$element][$size])) {
804
-                    $groups[] = $size;
805
-
806
-                    break 2;
807
-                }
808
-            }
809
-        }
810
-
811
-        return \array_unique($groups);
812
-    }
813
-
814
-    /**
815
-     * Returns the size of the test.
816
-     *
817
-     * @param string $className
818
-     * @param string $methodName
819
-     *
820
-     * @return int
821
-     */
822
-    public static function getSize($className, $methodName)
823
-    {
824
-        $groups = \array_flip(self::getGroups($className, $methodName));
825
-        $class  = new ReflectionClass($className);
826
-
827
-        if (isset($groups['large']) ||
828
-            (\class_exists('PHPUnit\DbUnit\TestCase', false) && $class->isSubclassOf('PHPUnit\DbUnit\TestCase'))) {
829
-            return self::LARGE;
830
-        }
831
-
832
-        if (isset($groups['medium'])) {
833
-            return self::MEDIUM;
834
-        }
835
-
836
-        if (isset($groups['small'])) {
837
-            return self::SMALL;
838
-        }
839
-
840
-        return self::UNKNOWN;
841
-    }
842
-
843
-    /**
844
-     * Returns the process isolation settings for a test.
845
-     *
846
-     * @param string $className
847
-     * @param string $methodName
848
-     *
849
-     * @return bool
850
-     */
851
-    public static function getProcessIsolationSettings($className, $methodName)
852
-    {
853
-        $annotations = self::parseTestMethodAnnotations(
854
-            $className,
855
-            $methodName
856
-        );
857
-
858
-        return isset($annotations['class']['runTestsInSeparateProcesses']) || isset($annotations['method']['runInSeparateProcess']);
859
-    }
860
-
861
-    public static function getClassProcessIsolationSettings($className, $methodName)
862
-    {
863
-        $annotations = self::parseTestMethodAnnotations(
864
-            $className,
865
-            $methodName
866
-        );
867
-
868
-        return isset($annotations['class']['runClassInSeparateProcess']);
869
-    }
870
-
871
-    /**
872
-     * Returns the preserve global state settings for a test.
873
-     *
874
-     * @param string $className
875
-     * @param string $methodName
876
-     *
877
-     * @return ?bool
878
-     */
879
-    public static function getPreserveGlobalStateSettings($className, $methodName)
880
-    {
881
-        return self::getBooleanAnnotationSetting(
882
-            $className,
883
-            $methodName,
884
-            'preserveGlobalState'
885
-        );
886
-    }
887
-
888
-    /**
889
-     * @param string $className
890
-     *
891
-     * @return array
892
-     */
893
-    public static function getHookMethods($className)
894
-    {
895
-        if (!\class_exists($className, false)) {
896
-            return self::emptyHookMethodsArray();
897
-        }
898
-
899
-        if (!isset(self::$hookMethods[$className])) {
900
-            self::$hookMethods[$className] = self::emptyHookMethodsArray();
901
-
902
-            try {
903
-                $class = new ReflectionClass($className);
904
-
905
-                foreach ($class->getMethods() as $method) {
906
-                    if (self::isBeforeClassMethod($method)) {
907
-                        \array_unshift(
908
-                            self::$hookMethods[$className]['beforeClass'],
909
-                            $method->getName()
910
-                        );
911
-                    }
912
-
913
-                    if (self::isBeforeMethod($method)) {
914
-                        \array_unshift(
915
-                            self::$hookMethods[$className]['before'],
916
-                            $method->getName()
917
-                        );
918
-                    }
919
-
920
-                    if (self::isAfterMethod($method)) {
921
-                        self::$hookMethods[$className]['after'][] = $method->getName();
922
-                    }
923
-
924
-                    if (self::isAfterClassMethod($method)) {
925
-                        self::$hookMethods[$className]['afterClass'][] = $method->getName();
926
-                    }
927
-                }
928
-            } catch (ReflectionException $e) {
929
-            }
930
-        }
931
-
932
-        return self::$hookMethods[$className];
933
-    }
934
-
935
-    /**
936
-     * @return array
937
-     */
938
-    private static function emptyHookMethodsArray()
939
-    {
940
-        return [
941
-            'beforeClass' => ['setUpBeforeClass'],
942
-            'before'      => ['setUp'],
943
-            'after'       => ['tearDown'],
944
-            'afterClass'  => ['tearDownAfterClass']
945
-        ];
946
-    }
947
-
948
-    /**
949
-     * @param string $className
950
-     * @param string $methodName
951
-     * @param string $settingName
952
-     *
953
-     * @return ?bool
954
-     */
955
-    private static function getBooleanAnnotationSetting($className, $methodName, $settingName)
956
-    {
957
-        $annotations = self::parseTestMethodAnnotations(
958
-            $className,
959
-            $methodName
960
-        );
961
-
962
-        if (isset($annotations['class'][$settingName])) {
963
-            if ($annotations['class'][$settingName][0] == 'enabled') {
964
-                return true;
965
-            }
966
-
967
-            if ($annotations['class'][$settingName][0] == 'disabled') {
968
-                return false;
969
-            }
970
-        }
971
-
972
-        if (isset($annotations['method'][$settingName])) {
973
-            if ($annotations['method'][$settingName][0] == 'enabled') {
974
-                return true;
975
-            }
976
-
977
-            if ($annotations['method'][$settingName][0] == 'disabled') {
978
-                return false;
979
-            }
980
-        }
981
-    }
982
-
983
-    /**
984
-     * @param string $element
985
-     *
986
-     * @return array
987
-     *
988
-     * @throws InvalidCoversTargetException
989
-     */
990
-    private static function resolveElementToReflectionObjects($element)
991
-    {
992
-        $codeToCoverList = [];
993
-
994
-        if (\strpos($element, '\\') !== false && \function_exists($element)) {
995
-            $codeToCoverList[] = new ReflectionFunction($element);
996
-        } elseif (\strpos($element, '::') !== false) {
997
-            list($className, $methodName) = \explode('::', $element);
998
-
999
-            if (isset($methodName[0]) && $methodName[0] == '<') {
1000
-                $classes = [$className];
1001
-
1002
-                foreach ($classes as $className) {
1003
-                    if (!\class_exists($className) &&
1004
-                        !\interface_exists($className) &&
1005
-                        !\trait_exists($className)) {
1006
-                        throw new InvalidCoversTargetException(
1007
-                            \sprintf(
1008
-                                'Trying to @cover or @use not existing class or ' .
1009
-                                'interface "%s".',
1010
-                                $className
1011
-                            )
1012
-                        );
1013
-                    }
1014
-
1015
-                    $class   = new ReflectionClass($className);
1016
-                    $methods = $class->getMethods();
1017
-                    $inverse = isset($methodName[1]) && $methodName[1] == '!';
1018
-
1019
-                    if (\strpos($methodName, 'protected')) {
1020
-                        $visibility = 'isProtected';
1021
-                    } elseif (\strpos($methodName, 'private')) {
1022
-                        $visibility = 'isPrivate';
1023
-                    } elseif (\strpos($methodName, 'public')) {
1024
-                        $visibility = 'isPublic';
1025
-                    }
1026
-
1027
-                    foreach ($methods as $method) {
1028
-                        if ($inverse && !$method->$visibility()) {
1029
-                            $codeToCoverList[] = $method;
1030
-                        } elseif (!$inverse && $method->$visibility()) {
1031
-                            $codeToCoverList[] = $method;
1032
-                        }
1033
-                    }
1034
-                }
1035
-            } else {
1036
-                $classes = [$className];
1037
-
1038
-                foreach ($classes as $className) {
1039
-                    if ($className == '' && \function_exists($methodName)) {
1040
-                        $codeToCoverList[] = new ReflectionFunction(
1041
-                            $methodName
1042
-                        );
1043
-                    } else {
1044
-                        if (!((\class_exists($className) || \interface_exists($className) || \trait_exists($className)) &&
1045
-                            \method_exists($className, $methodName))) {
1046
-                            throw new InvalidCoversTargetException(
1047
-                                \sprintf(
1048
-                                    'Trying to @cover or @use not existing method "%s::%s".',
1049
-                                    $className,
1050
-                                    $methodName
1051
-                                )
1052
-                            );
1053
-                        }
1054
-
1055
-                        $codeToCoverList[] = new ReflectionMethod(
1056
-                            $className,
1057
-                            $methodName
1058
-                        );
1059
-                    }
1060
-                }
1061
-            }
1062
-        } else {
1063
-            $extended = false;
1064
-
1065
-            if (\strpos($element, '<extended>') !== false) {
1066
-                $element  = \str_replace('<extended>', '', $element);
1067
-                $extended = true;
1068
-            }
1069
-
1070
-            $classes = [$element];
1071
-
1072
-            if ($extended) {
1073
-                $classes = \array_merge(
1074
-                    $classes,
1075
-                    \class_implements($element),
1076
-                    \class_parents($element)
1077
-                );
1078
-            }
1079
-
1080
-            foreach ($classes as $className) {
1081
-                if (!\class_exists($className) &&
1082
-                    !\interface_exists($className) &&
1083
-                    !\trait_exists($className)) {
1084
-                    throw new InvalidCoversTargetException(
1085
-                        \sprintf(
1086
-                            'Trying to @cover or @use not existing class or ' .
1087
-                            'interface "%s".',
1088
-                            $className
1089
-                        )
1090
-                    );
1091
-                }
1092
-
1093
-                $codeToCoverList[] = new ReflectionClass($className);
1094
-            }
1095
-        }
1096
-
1097
-        return $codeToCoverList;
1098
-    }
1099
-
1100
-    /**
1101
-     * @param array $reflectors
1102
-     *
1103
-     * @return array
1104
-     */
1105
-    private static function resolveReflectionObjectsToLines(array $reflectors)
1106
-    {
1107
-        $result = [];
1108
-
1109
-        foreach ($reflectors as $reflector) {
1110
-            $filename = $reflector->getFileName();
1111
-
1112
-            if (!isset($result[$filename])) {
1113
-                $result[$filename] = [];
1114
-            }
1115
-
1116
-            $result[$filename] = \array_merge(
1117
-                $result[$filename],
1118
-                \range($reflector->getStartLine(), $reflector->getEndLine())
1119
-            );
1120
-        }
1121
-
1122
-        foreach ($result as $filename => $lineNumbers) {
1123
-            $result[$filename] = \array_keys(\array_flip($lineNumbers));
1124
-        }
1125
-
1126
-        return $result;
1127
-    }
1128
-
1129
-    /**
1130
-     * @param ReflectionMethod $method
1131
-     *
1132
-     * @return bool
1133
-     */
1134
-    private static function isBeforeClassMethod(ReflectionMethod $method)
1135
-    {
1136
-        return $method->isStatic() && \strpos($method->getDocComment(), '@beforeClass') !== false;
1137
-    }
1138
-
1139
-    /**
1140
-     * @param ReflectionMethod $method
1141
-     *
1142
-     * @return bool
1143
-     */
1144
-    private static function isBeforeMethod(ReflectionMethod $method)
1145
-    {
1146
-        return \preg_match('/@before\b/', $method->getDocComment()) > 0;
1147
-    }
1148
-
1149
-    /**
1150
-     * @param ReflectionMethod $method
1151
-     *
1152
-     * @return bool
1153
-     */
1154
-    private static function isAfterClassMethod(ReflectionMethod $method)
1155
-    {
1156
-        return $method->isStatic() && \strpos($method->getDocComment(), '@afterClass') !== false;
1157
-    }
1158
-
1159
-    /**
1160
-     * @param ReflectionMethod $method
1161
-     *
1162
-     * @return bool
1163
-     */
1164
-    private static function isAfterMethod(ReflectionMethod $method)
1165
-    {
1166
-        return \preg_match('/@after\b/', $method->getDocComment()) > 0;
1167
-    }
1168
-
1169
-    /**
1170
-     * Trims any extensions from version string that follows after
1171
-     * the <major>.<minor>[.<patch>] format
1172
-     *
1173
-     * @param $version (Optional)
1174
-     *
1175
-     * @return mixed
1176
-     */
1177
-    private static function sanitizeVersionNumber($version)
1178
-    {
1179
-        return \preg_replace(
1180
-            '/^(\d+\.\d+(?:.\d+)?).*$/',
1181
-            '$1',
1182
-            $version
1183
-        );
1184
-    }
34
+	const REGEX_DATA_PROVIDER               = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/';
35
+	const REGEX_TEST_WITH                   = '/@testWith\s+/';
36
+	const REGEX_EXPECTED_EXCEPTION          = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m';
37
+	const REGEX_REQUIRES_VERSION            = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
38
+	const REGEX_REQUIRES_VERSION_CONSTRAINT = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<constraint>[\d\t -.|~^]+)[ \t]*\r?$/m';
39
+	const REGEX_REQUIRES_OS                 = '/@requires\s+(?P<name>OS(?:FAMILY)?)\s+(?P<value>.+?)[ \t]*\r?$/m';
40
+	const REGEX_REQUIRES                    = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^ ]+?))\s*(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+[\d\.]?)?[ \t]*\r?$/m';
41
+
42
+	const UNKNOWN = -1;
43
+	const SMALL   = 0;
44
+	const MEDIUM  = 1;
45
+	const LARGE   = 2;
46
+
47
+	private static $annotationCache = [];
48
+
49
+	private static $hookMethods = [];
50
+
51
+	/**
52
+	 * @param \PHPUnit\Framework\Test $test
53
+	 * @param bool                    $asString
54
+	 *
55
+	 * @return mixed
56
+	 */
57
+	public static function describe(\PHPUnit\Framework\Test $test, $asString = true)
58
+	{
59
+		if ($asString) {
60
+			if ($test instanceof SelfDescribing) {
61
+				return $test->toString();
62
+			}
63
+
64
+			return \get_class($test);
65
+		}
66
+
67
+		if ($test instanceof TestCase) {
68
+			return [
69
+				\get_class($test), $test->getName()
70
+			];
71
+		}
72
+
73
+		if ($test instanceof SelfDescribing) {
74
+			return ['', $test->toString()];
75
+		}
76
+
77
+		return ['', \get_class($test)];
78
+	}
79
+
80
+	/**
81
+	 * @param string $className
82
+	 * @param string $methodName
83
+	 *
84
+	 * @return array|bool
85
+	 *
86
+	 * @throws CodeCoverageException
87
+	 */
88
+	public static function getLinesToBeCovered($className, $methodName)
89
+	{
90
+		$annotations = self::parseTestMethodAnnotations(
91
+			$className,
92
+			$methodName
93
+		);
94
+
95
+		if (isset($annotations['class']['coversNothing']) || isset($annotations['method']['coversNothing'])) {
96
+			return false;
97
+		}
98
+
99
+		return self::getLinesToBeCoveredOrUsed($className, $methodName, 'covers');
100
+	}
101
+
102
+	/**
103
+	 * Returns lines of code specified with the @uses annotation.
104
+	 *
105
+	 * @param string $className
106
+	 * @param string $methodName
107
+	 *
108
+	 * @return array
109
+	 */
110
+	public static function getLinesToBeUsed($className, $methodName)
111
+	{
112
+		return self::getLinesToBeCoveredOrUsed($className, $methodName, 'uses');
113
+	}
114
+
115
+	/**
116
+	 * @param string $className
117
+	 * @param string $methodName
118
+	 * @param string $mode
119
+	 *
120
+	 * @return array
121
+	 *
122
+	 * @throws CodeCoverageException
123
+	 */
124
+	private static function getLinesToBeCoveredOrUsed($className, $methodName, $mode)
125
+	{
126
+		$annotations = self::parseTestMethodAnnotations(
127
+			$className,
128
+			$methodName
129
+		);
130
+
131
+		$classShortcut = null;
132
+
133
+		if (!empty($annotations['class'][$mode . 'DefaultClass'])) {
134
+			if (\count($annotations['class'][$mode . 'DefaultClass']) > 1) {
135
+				throw new CodeCoverageException(
136
+					\sprintf(
137
+						'More than one @%sClass annotation in class or interface "%s".',
138
+						$mode,
139
+						$className
140
+					)
141
+				);
142
+			}
143
+
144
+			$classShortcut = $annotations['class'][$mode . 'DefaultClass'][0];
145
+		}
146
+
147
+		$list = [];
148
+
149
+		if (isset($annotations['class'][$mode])) {
150
+			$list = $annotations['class'][$mode];
151
+		}
152
+
153
+		if (isset($annotations['method'][$mode])) {
154
+			$list = \array_merge($list, $annotations['method'][$mode]);
155
+		}
156
+
157
+		$codeList = [];
158
+
159
+		foreach (\array_unique($list) as $element) {
160
+			if ($classShortcut && \strncmp($element, '::', 2) === 0) {
161
+				$element = $classShortcut . $element;
162
+			}
163
+
164
+			$element = \preg_replace('/[\s()]+$/', '', $element);
165
+			$element = \explode(' ', $element);
166
+			$element = $element[0];
167
+
168
+			$codeList = \array_merge(
169
+				$codeList,
170
+				self::resolveElementToReflectionObjects($element)
171
+			);
172
+		}
173
+
174
+		return self::resolveReflectionObjectsToLines($codeList);
175
+	}
176
+
177
+	/**
178
+	 * Returns the requirements for a test.
179
+	 *
180
+	 * @param string $className
181
+	 * @param string $methodName
182
+	 *
183
+	 * @return array
184
+	 */
185
+	public static function getRequirements($className, $methodName)
186
+	{
187
+		$reflector  = new ReflectionClass($className);
188
+		$docComment = $reflector->getDocComment();
189
+		$reflector  = new ReflectionMethod($className, $methodName);
190
+		$docComment .= "\n" . $reflector->getDocComment();
191
+		$requires = [];
192
+
193
+		if ($count = \preg_match_all(self::REGEX_REQUIRES_OS, $docComment, $matches)) {
194
+			foreach (\range(0, $count - 1) as $i) {
195
+				$requires[$matches['name'][$i]] = $matches['value'][$i];
196
+			}
197
+		}
198
+
199
+		if ($count = \preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) {
200
+			foreach (\range(0, $count - 1) as $i) {
201
+				$requires[$matches['name'][$i]] = [
202
+					'version'  => $matches['version'][$i],
203
+					'operator' => $matches['operator'][$i]
204
+				];
205
+			}
206
+		}
207
+		if ($count = \preg_match_all(self::REGEX_REQUIRES_VERSION_CONSTRAINT, $docComment, $matches)) {
208
+			foreach (\range(0, $count - 1) as $i) {
209
+				if (!empty($requires[$matches['name'][$i]])) {
210
+					continue;
211
+				}
212
+
213
+				try {
214
+					$versionConstraintParser = new VersionConstraintParser;
215
+
216
+					$requires[$matches['name'][$i] . '_constraint'] = [
217
+						'constraint' => $versionConstraintParser->parse(\trim($matches['constraint'][$i]))
218
+					];
219
+				} catch (\PharIo\Version\Exception $e) {
220
+					throw new Warning($e->getMessage(), $e->getCode(), $e);
221
+				}
222
+			}
223
+		}
224
+
225
+		if ($count = \preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) {
226
+			foreach (\range(0, $count - 1) as $i) {
227
+				$name = $matches['name'][$i] . 's';
228
+
229
+				if (!isset($requires[$name])) {
230
+					$requires[$name] = [];
231
+				}
232
+
233
+				$requires[$name][] = $matches['value'][$i];
234
+
235
+				if (empty($matches['version'][$i]) || $name != 'extensions') {
236
+					continue;
237
+				}
238
+
239
+				$requires['extension_versions'][$matches['value'][$i]] = [
240
+					'version'  => $matches['version'][$i],
241
+					'operator' => $matches['operator'][$i]
242
+				];
243
+			}
244
+		}
245
+
246
+		return $requires;
247
+	}
248
+
249
+	/**
250
+	 * Returns the missing requirements for a test.
251
+	 *
252
+	 * @param string $className
253
+	 * @param string $methodName
254
+	 *
255
+	 * @return string[]
256
+	 */
257
+	public static function getMissingRequirements($className, $methodName)
258
+	{
259
+		$required = static::getRequirements($className, $methodName);
260
+		$missing  = [];
261
+
262
+		if (!empty($required['PHP'])) {
263
+			$operator = empty($required['PHP']['operator']) ? '>=' : $required['PHP']['operator'];
264
+
265
+			if (!\version_compare(PHP_VERSION, $required['PHP']['version'], $operator)) {
266
+				$missing[] = \sprintf('PHP %s %s is required.', $operator, $required['PHP']['version']);
267
+			}
268
+		} elseif (!empty($required['PHP_constraint'])) {
269
+			$version = new \PharIo\Version\Version(self::sanitizeVersionNumber(PHP_VERSION));
270
+
271
+			if (!$required['PHP_constraint']['constraint']->complies($version)) {
272
+				$missing[] = \sprintf(
273
+					'PHP version does not match the required constraint %s.',
274
+					$required['PHP_constraint']['constraint']->asString()
275
+				);
276
+			}
277
+		}
278
+
279
+		if (!empty($required['PHPUnit'])) {
280
+			$phpunitVersion = Version::id();
281
+
282
+			$operator = empty($required['PHPUnit']['operator']) ? '>=' : $required['PHPUnit']['operator'];
283
+
284
+			if (!\version_compare($phpunitVersion, $required['PHPUnit']['version'], $operator)) {
285
+				$missing[] = \sprintf('PHPUnit %s %s is required.', $operator, $required['PHPUnit']['version']);
286
+			}
287
+		} elseif (!empty($required['PHPUnit_constraint'])) {
288
+			$phpunitVersion = new \PharIo\Version\Version(self::sanitizeVersionNumber(Version::id()));
289
+
290
+			if (!$required['PHPUnit_constraint']['constraint']->complies($phpunitVersion)) {
291
+				$missing[] = \sprintf(
292
+					'PHPUnit version does not match the required constraint %s.',
293
+					$required['PHPUnit_constraint']['constraint']->asString()
294
+				);
295
+			}
296
+		}
297
+
298
+		if (!empty($required['OSFAMILY']) && $required['OSFAMILY'] !== (new OperatingSystem())->getFamily()) {
299
+			$missing[] = \sprintf('Operating system %s is required.', $required['OSFAMILY']);
300
+		}
301
+
302
+		if (!empty($required['OS'])) {
303
+			$requiredOsPattern = \sprintf('/%s/i', \addcslashes($required['OS'], '/'));
304
+			if (!\preg_match($requiredOsPattern, PHP_OS)) {
305
+				$missing[] = \sprintf('Operating system matching %s is required.', $requiredOsPattern);
306
+			}
307
+		}
308
+
309
+		if (!empty($required['functions'])) {
310
+			foreach ($required['functions'] as $function) {
311
+				$pieces = \explode('::', $function);
312
+
313
+				if (2 === \count($pieces) && \method_exists($pieces[0], $pieces[1])) {
314
+					continue;
315
+				}
316
+
317
+				if (\function_exists($function)) {
318
+					continue;
319
+				}
320
+
321
+				$missing[] = \sprintf('Function %s is required.', $function);
322
+			}
323
+		}
324
+
325
+		if (!empty($required['extensions'])) {
326
+			foreach ($required['extensions'] as $extension) {
327
+				if (isset($required['extension_versions'][$extension])) {
328
+					continue;
329
+				}
330
+
331
+				if (!\extension_loaded($extension)) {
332
+					$missing[] = \sprintf('Extension %s is required.', $extension);
333
+				}
334
+			}
335
+		}
336
+
337
+		if (!empty($required['extension_versions'])) {
338
+			foreach ($required['extension_versions'] as $extension => $required) {
339
+				$actualVersion = \phpversion($extension);
340
+
341
+				$operator = empty($required['operator']) ? '>=' : $required['operator'];
342
+
343
+				if (false === $actualVersion || !\version_compare($actualVersion, $required['version'], $operator)) {
344
+					$missing[] = \sprintf('Extension %s %s %s is required.', $extension, $operator, $required['version']);
345
+				}
346
+			}
347
+		}
348
+
349
+		return $missing;
350
+	}
351
+
352
+	/**
353
+	 * Returns the expected exception for a test.
354
+	 *
355
+	 * @param string $className
356
+	 * @param string $methodName
357
+	 *
358
+	 * @return array|false
359
+	 */
360
+	public static function getExpectedException($className, $methodName)
361
+	{
362
+		$reflector  = new ReflectionMethod($className, $methodName);
363
+		$docComment = $reflector->getDocComment();
364
+		$docComment = \substr($docComment, 3, -2);
365
+
366
+		if (\preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) {
367
+			$annotations = self::parseTestMethodAnnotations(
368
+				$className,
369
+				$methodName
370
+			);
371
+
372
+			$class         = $matches[1];
373
+			$code          = null;
374
+			$message       = '';
375
+			$messageRegExp = '';
376
+
377
+			if (isset($matches[2])) {
378
+				$message = \trim($matches[2]);
379
+			} elseif (isset($annotations['method']['expectedExceptionMessage'])) {
380
+				$message = self::parseAnnotationContent(
381
+					$annotations['method']['expectedExceptionMessage'][0]
382
+				);
383
+			}
384
+
385
+			if (isset($annotations['method']['expectedExceptionMessageRegExp'])) {
386
+				$messageRegExp = self::parseAnnotationContent(
387
+					$annotations['method']['expectedExceptionMessageRegExp'][0]
388
+				);
389
+			}
390
+
391
+			if (isset($matches[3])) {
392
+				$code = $matches[3];
393
+			} elseif (isset($annotations['method']['expectedExceptionCode'])) {
394
+				$code = self::parseAnnotationContent(
395
+					$annotations['method']['expectedExceptionCode'][0]
396
+				);
397
+			}
398
+
399
+			if (\is_numeric($code)) {
400
+				$code = (int) $code;
401
+			} elseif (\is_string($code) && \defined($code)) {
402
+				$code = (int) \constant($code);
403
+			}
404
+
405
+			return [
406
+				'class' => $class, 'code' => $code, 'message' => $message, 'message_regex' => $messageRegExp
407
+			];
408
+		}
409
+
410
+		return false;
411
+	}
412
+
413
+	/**
414
+	 * Parse annotation content to use constant/class constant values
415
+	 *
416
+	 * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME
417
+	 *
418
+	 * If the constant is not found the string is used as is to ensure maximum BC.
419
+	 *
420
+	 * @param string $message
421
+	 *
422
+	 * @return string
423
+	 */
424
+	private static function parseAnnotationContent($message)
425
+	{
426
+		if ((\strpos($message, '::') !== false && \count(\explode('::', $message)) == 2) && \defined($message)) {
427
+			$message = \constant($message);
428
+		}
429
+
430
+		return $message;
431
+	}
432
+
433
+	/**
434
+	 * Returns the provided data for a method.
435
+	 *
436
+	 * @param string $className
437
+	 * @param string $methodName
438
+	 *
439
+	 * @return array When a data provider is specified and exists
440
+	 *               null  When no data provider is specified
441
+	 *
442
+	 * @throws Exception
443
+	 */
444
+	public static function getProvidedData($className, $methodName)
445
+	{
446
+		$reflector  = new ReflectionMethod($className, $methodName);
447
+		$docComment = $reflector->getDocComment();
448
+
449
+		$data = self::getDataFromDataProviderAnnotation($docComment, $className, $methodName);
450
+
451
+		if ($data === null) {
452
+			$data = self::getDataFromTestWithAnnotation($docComment);
453
+		}
454
+
455
+		if (\is_array($data) && empty($data)) {
456
+			throw new SkippedTestError;
457
+		}
458
+
459
+		if ($data !== null) {
460
+			foreach ($data as $key => $value) {
461
+				if (!\is_array($value)) {
462
+					throw new Exception(
463
+						\sprintf(
464
+							'Data set %s is invalid.',
465
+							\is_int($key) ? '#' . $key : '"' . $key . '"'
466
+						)
467
+					);
468
+				}
469
+			}
470
+		}
471
+
472
+		return $data;
473
+	}
474
+
475
+	/**
476
+	 * Returns the provided data for a method.
477
+	 *
478
+	 * @param string $docComment
479
+	 * @param string $className
480
+	 * @param string $methodName
481
+	 *
482
+	 * @return array|Iterator when a data provider is specified and exists
483
+	 *                        null           when no data provider is specified
484
+	 *
485
+	 * @throws Exception
486
+	 */
487
+	private static function getDataFromDataProviderAnnotation($docComment, $className, $methodName)
488
+	{
489
+		if (\preg_match_all(self::REGEX_DATA_PROVIDER, $docComment, $matches)) {
490
+			$result = [];
491
+
492
+			foreach ($matches[1] as $match) {
493
+				$dataProviderMethodNameNamespace = \explode('\\', $match);
494
+				$leaf                            = \explode('::', \array_pop($dataProviderMethodNameNamespace));
495
+				$dataProviderMethodName          = \array_pop($leaf);
496
+
497
+				if (!empty($dataProviderMethodNameNamespace)) {
498
+					$dataProviderMethodNameNamespace = \implode('\\', $dataProviderMethodNameNamespace) . '\\';
499
+				} else {
500
+					$dataProviderMethodNameNamespace = '';
501
+				}
502
+
503
+				if (!empty($leaf)) {
504
+					$dataProviderClassName = $dataProviderMethodNameNamespace . \array_pop($leaf);
505
+				} else {
506
+					$dataProviderClassName = $className;
507
+				}
508
+
509
+				$dataProviderClass  = new ReflectionClass($dataProviderClassName);
510
+				$dataProviderMethod = $dataProviderClass->getMethod(
511
+					$dataProviderMethodName
512
+				);
513
+
514
+				if ($dataProviderMethod->isStatic()) {
515
+					$object = null;
516
+				} else {
517
+					$object = $dataProviderClass->newInstance();
518
+				}
519
+
520
+				if ($dataProviderMethod->getNumberOfParameters() == 0) {
521
+					$data = $dataProviderMethod->invoke($object);
522
+				} else {
523
+					$data = $dataProviderMethod->invoke($object, $methodName);
524
+				}
525
+
526
+				if ($data instanceof Traversable) {
527
+					$data = \iterator_to_array($data, false);
528
+				}
529
+
530
+				if (\is_array($data)) {
531
+					$result = \array_merge($result, $data);
532
+				}
533
+			}
534
+
535
+			return $result;
536
+		}
537
+	}
538
+
539
+	/**
540
+	 * @param string $docComment full docComment string
541
+	 *
542
+	 * @return array|null array when @testWith annotation is defined,
543
+	 *                    null when @testWith annotation is omitted
544
+	 *
545
+	 * @throws Exception when @testWith annotation is defined but cannot be parsed
546
+	 */
547
+	public static function getDataFromTestWithAnnotation($docComment)
548
+	{
549
+		$docComment = self::cleanUpMultiLineAnnotation($docComment);
550
+
551
+		if (\preg_match(self::REGEX_TEST_WITH, $docComment, $matches, PREG_OFFSET_CAPTURE)) {
552
+			$offset            = \strlen($matches[0][0]) + $matches[0][1];
553
+			$annotationContent = \substr($docComment, $offset);
554
+			$data              = [];
555
+
556
+			foreach (\explode("\n", $annotationContent) as $candidateRow) {
557
+				$candidateRow = \trim($candidateRow);
558
+
559
+				if ($candidateRow[0] !== '[') {
560
+					break;
561
+				}
562
+
563
+				$dataSet = \json_decode($candidateRow, true);
564
+
565
+				if (\json_last_error() != JSON_ERROR_NONE) {
566
+					throw new Exception(
567
+						'The dataset for the @testWith annotation cannot be parsed: ' . \json_last_error_msg()
568
+					);
569
+				}
570
+
571
+				$data[] = $dataSet;
572
+			}
573
+
574
+			if (!$data) {
575
+				throw new Exception('The dataset for the @testWith annotation cannot be parsed.');
576
+			}
577
+
578
+			return $data;
579
+		}
580
+	}
581
+
582
+	private static function cleanUpMultiLineAnnotation($docComment)
583
+	{
584
+		//removing initial '   * ' for docComment
585
+		$docComment = \str_replace("\r\n", "\n", $docComment);
586
+		$docComment = \preg_replace('/' . '\n' . '\s*' . '\*' . '\s?' . '/', "\n", $docComment);
587
+		$docComment = \substr($docComment, 0, -1);
588
+		$docComment = \rtrim($docComment, "\n");
589
+
590
+		return $docComment;
591
+	}
592
+
593
+	/**
594
+	 * @param string $className
595
+	 * @param string $methodName
596
+	 *
597
+	 * @return array
598
+	 *
599
+	 * @throws ReflectionException
600
+	 */
601
+	public static function parseTestMethodAnnotations($className, $methodName = '')
602
+	{
603
+		if (!isset(self::$annotationCache[$className])) {
604
+			$class       = new ReflectionClass($className);
605
+			$traits      = $class->getTraits();
606
+			$annotations = [];
607
+
608
+			foreach ($traits as $trait) {
609
+				$annotations = \array_merge(
610
+					$annotations,
611
+					self::parseAnnotations($trait->getDocComment())
612
+				);
613
+			}
614
+
615
+			self::$annotationCache[$className] = \array_merge(
616
+				$annotations,
617
+				self::parseAnnotations($class->getDocComment())
618
+			);
619
+		}
620
+
621
+		if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) {
622
+			try {
623
+				$method      = new ReflectionMethod($className, $methodName);
624
+				$annotations = self::parseAnnotations($method->getDocComment());
625
+			} catch (ReflectionException $e) {
626
+				$annotations = [];
627
+			}
628
+
629
+			self::$annotationCache[$className . '::' . $methodName] = $annotations;
630
+		}
631
+
632
+		return [
633
+			'class'  => self::$annotationCache[$className],
634
+			'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : []
635
+		];
636
+	}
637
+
638
+	/**
639
+	 * @param string $className
640
+	 * @param string $methodName
641
+	 *
642
+	 * @return array
643
+	 */
644
+	public static function getInlineAnnotations($className, $methodName)
645
+	{
646
+		$method      = new ReflectionMethod($className, $methodName);
647
+		$code        = \file($method->getFileName());
648
+		$lineNumber  = $method->getStartLine();
649
+		$startLine   = $method->getStartLine() - 1;
650
+		$endLine     = $method->getEndLine() - 1;
651
+		$methodLines = \array_slice($code, $startLine, $endLine - $startLine + 1);
652
+		$annotations = [];
653
+
654
+		foreach ($methodLines as $line) {
655
+			if (\preg_match('#/\*\*?\s*@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?\*/$#m', $line, $matches)) {
656
+				$annotations[\strtolower($matches['name'])] = [
657
+					'line'  => $lineNumber,
658
+					'value' => $matches['value']
659
+				];
660
+			}
661
+
662
+			$lineNumber++;
663
+		}
664
+
665
+		return $annotations;
666
+	}
667
+
668
+	/**
669
+	 * @param string $docblock
670
+	 *
671
+	 * @return array
672
+	 */
673
+	private static function parseAnnotations($docblock)
674
+	{
675
+		$annotations = [];
676
+		// Strip away the docblock header and footer to ease parsing of one line annotations
677
+		$docblock = \substr($docblock, 3, -2);
678
+
679
+		if (\preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docblock, $matches)) {
680
+			$numMatches = \count($matches[0]);
681
+
682
+			for ($i = 0; $i < $numMatches; ++$i) {
683
+				$annotations[$matches['name'][$i]][] = (string) $matches['value'][$i];
684
+			}
685
+		}
686
+
687
+		return $annotations;
688
+	}
689
+
690
+	/**
691
+	 * Returns the backup settings for a test.
692
+	 *
693
+	 * @param string $className
694
+	 * @param string $methodName
695
+	 *
696
+	 * @return array<string, bool|null>
697
+	 */
698
+	public static function getBackupSettings($className, $methodName)
699
+	{
700
+		return [
701
+			'backupGlobals' => self::getBooleanAnnotationSetting(
702
+				$className,
703
+				$methodName,
704
+				'backupGlobals'
705
+			),
706
+			'backupStaticAttributes' => self::getBooleanAnnotationSetting(
707
+				$className,
708
+				$methodName,
709
+				'backupStaticAttributes'
710
+			)
711
+		];
712
+	}
713
+
714
+	/**
715
+	 * Returns the dependencies for a test class or method.
716
+	 *
717
+	 * @param string $className
718
+	 * @param string $methodName
719
+	 *
720
+	 * @return array
721
+	 */
722
+	public static function getDependencies($className, $methodName)
723
+	{
724
+		$annotations = self::parseTestMethodAnnotations(
725
+			$className,
726
+			$methodName
727
+		);
728
+
729
+		$dependencies = [];
730
+
731
+		if (isset($annotations['class']['depends'])) {
732
+			$dependencies = $annotations['class']['depends'];
733
+		}
734
+
735
+		if (isset($annotations['method']['depends'])) {
736
+			$dependencies = \array_merge(
737
+				$dependencies,
738
+				$annotations['method']['depends']
739
+			);
740
+		}
741
+
742
+		return \array_unique($dependencies);
743
+	}
744
+
745
+	/**
746
+	 * Returns the error handler settings for a test.
747
+	 *
748
+	 * @param string $className
749
+	 * @param string $methodName
750
+	 *
751
+	 * @return ?bool
752
+	 */
753
+	public static function getErrorHandlerSettings($className, $methodName)
754
+	{
755
+		return self::getBooleanAnnotationSetting(
756
+			$className,
757
+			$methodName,
758
+			'errorHandler'
759
+		);
760
+	}
761
+
762
+	/**
763
+	 * Returns the groups for a test class or method.
764
+	 *
765
+	 * @param string $className
766
+	 * @param string $methodName
767
+	 *
768
+	 * @return array
769
+	 */
770
+	public static function getGroups($className, $methodName = '')
771
+	{
772
+		$annotations = self::parseTestMethodAnnotations(
773
+			$className,
774
+			$methodName
775
+		);
776
+
777
+		$groups = [];
778
+
779
+		if (isset($annotations['method']['author'])) {
780
+			$groups = $annotations['method']['author'];
781
+		} elseif (isset($annotations['class']['author'])) {
782
+			$groups = $annotations['class']['author'];
783
+		}
784
+
785
+		if (isset($annotations['class']['group'])) {
786
+			$groups = \array_merge($groups, $annotations['class']['group']);
787
+		}
788
+
789
+		if (isset($annotations['method']['group'])) {
790
+			$groups = \array_merge($groups, $annotations['method']['group']);
791
+		}
792
+
793
+		if (isset($annotations['class']['ticket'])) {
794
+			$groups = \array_merge($groups, $annotations['class']['ticket']);
795
+		}
796
+
797
+		if (isset($annotations['method']['ticket'])) {
798
+			$groups = \array_merge($groups, $annotations['method']['ticket']);
799
+		}
800
+
801
+		foreach (['method', 'class'] as $element) {
802
+			foreach (['small', 'medium', 'large'] as $size) {
803
+				if (isset($annotations[$element][$size])) {
804
+					$groups[] = $size;
805
+
806
+					break 2;
807
+				}
808
+			}
809
+		}
810
+
811
+		return \array_unique($groups);
812
+	}
813
+
814
+	/**
815
+	 * Returns the size of the test.
816
+	 *
817
+	 * @param string $className
818
+	 * @param string $methodName
819
+	 *
820
+	 * @return int
821
+	 */
822
+	public static function getSize($className, $methodName)
823
+	{
824
+		$groups = \array_flip(self::getGroups($className, $methodName));
825
+		$class  = new ReflectionClass($className);
826
+
827
+		if (isset($groups['large']) ||
828
+			(\class_exists('PHPUnit\DbUnit\TestCase', false) && $class->isSubclassOf('PHPUnit\DbUnit\TestCase'))) {
829
+			return self::LARGE;
830
+		}
831
+
832
+		if (isset($groups['medium'])) {
833
+			return self::MEDIUM;
834
+		}
835
+
836
+		if (isset($groups['small'])) {
837
+			return self::SMALL;
838
+		}
839
+
840
+		return self::UNKNOWN;
841
+	}
842
+
843
+	/**
844
+	 * Returns the process isolation settings for a test.
845
+	 *
846
+	 * @param string $className
847
+	 * @param string $methodName
848
+	 *
849
+	 * @return bool
850
+	 */
851
+	public static function getProcessIsolationSettings($className, $methodName)
852
+	{
853
+		$annotations = self::parseTestMethodAnnotations(
854
+			$className,
855
+			$methodName
856
+		);
857
+
858
+		return isset($annotations['class']['runTestsInSeparateProcesses']) || isset($annotations['method']['runInSeparateProcess']);
859
+	}
860
+
861
+	public static function getClassProcessIsolationSettings($className, $methodName)
862
+	{
863
+		$annotations = self::parseTestMethodAnnotations(
864
+			$className,
865
+			$methodName
866
+		);
867
+
868
+		return isset($annotations['class']['runClassInSeparateProcess']);
869
+	}
870
+
871
+	/**
872
+	 * Returns the preserve global state settings for a test.
873
+	 *
874
+	 * @param string $className
875
+	 * @param string $methodName
876
+	 *
877
+	 * @return ?bool
878
+	 */
879
+	public static function getPreserveGlobalStateSettings($className, $methodName)
880
+	{
881
+		return self::getBooleanAnnotationSetting(
882
+			$className,
883
+			$methodName,
884
+			'preserveGlobalState'
885
+		);
886
+	}
887
+
888
+	/**
889
+	 * @param string $className
890
+	 *
891
+	 * @return array
892
+	 */
893
+	public static function getHookMethods($className)
894
+	{
895
+		if (!\class_exists($className, false)) {
896
+			return self::emptyHookMethodsArray();
897
+		}
898
+
899
+		if (!isset(self::$hookMethods[$className])) {
900
+			self::$hookMethods[$className] = self::emptyHookMethodsArray();
901
+
902
+			try {
903
+				$class = new ReflectionClass($className);
904
+
905
+				foreach ($class->getMethods() as $method) {
906
+					if (self::isBeforeClassMethod($method)) {
907
+						\array_unshift(
908
+							self::$hookMethods[$className]['beforeClass'],
909
+							$method->getName()
910
+						);
911
+					}
912
+
913
+					if (self::isBeforeMethod($method)) {
914
+						\array_unshift(
915
+							self::$hookMethods[$className]['before'],
916
+							$method->getName()
917
+						);
918
+					}
919
+
920
+					if (self::isAfterMethod($method)) {
921
+						self::$hookMethods[$className]['after'][] = $method->getName();
922
+					}
923
+
924
+					if (self::isAfterClassMethod($method)) {
925
+						self::$hookMethods[$className]['afterClass'][] = $method->getName();
926
+					}
927
+				}
928
+			} catch (ReflectionException $e) {
929
+			}
930
+		}
931
+
932
+		return self::$hookMethods[$className];
933
+	}
934
+
935
+	/**
936
+	 * @return array
937
+	 */
938
+	private static function emptyHookMethodsArray()
939
+	{
940
+		return [
941
+			'beforeClass' => ['setUpBeforeClass'],
942
+			'before'      => ['setUp'],
943
+			'after'       => ['tearDown'],
944
+			'afterClass'  => ['tearDownAfterClass']
945
+		];
946
+	}
947
+
948
+	/**
949
+	 * @param string $className
950
+	 * @param string $methodName
951
+	 * @param string $settingName
952
+	 *
953
+	 * @return ?bool
954
+	 */
955
+	private static function getBooleanAnnotationSetting($className, $methodName, $settingName)
956
+	{
957
+		$annotations = self::parseTestMethodAnnotations(
958
+			$className,
959
+			$methodName
960
+		);
961
+
962
+		if (isset($annotations['class'][$settingName])) {
963
+			if ($annotations['class'][$settingName][0] == 'enabled') {
964
+				return true;
965
+			}
966
+
967
+			if ($annotations['class'][$settingName][0] == 'disabled') {
968
+				return false;
969
+			}
970
+		}
971
+
972
+		if (isset($annotations['method'][$settingName])) {
973
+			if ($annotations['method'][$settingName][0] == 'enabled') {
974
+				return true;
975
+			}
976
+
977
+			if ($annotations['method'][$settingName][0] == 'disabled') {
978
+				return false;
979
+			}
980
+		}
981
+	}
982
+
983
+	/**
984
+	 * @param string $element
985
+	 *
986
+	 * @return array
987
+	 *
988
+	 * @throws InvalidCoversTargetException
989
+	 */
990
+	private static function resolveElementToReflectionObjects($element)
991
+	{
992
+		$codeToCoverList = [];
993
+
994
+		if (\strpos($element, '\\') !== false && \function_exists($element)) {
995
+			$codeToCoverList[] = new ReflectionFunction($element);
996
+		} elseif (\strpos($element, '::') !== false) {
997
+			list($className, $methodName) = \explode('::', $element);
998
+
999
+			if (isset($methodName[0]) && $methodName[0] == '<') {
1000
+				$classes = [$className];
1001
+
1002
+				foreach ($classes as $className) {
1003
+					if (!\class_exists($className) &&
1004
+						!\interface_exists($className) &&
1005
+						!\trait_exists($className)) {
1006
+						throw new InvalidCoversTargetException(
1007
+							\sprintf(
1008
+								'Trying to @cover or @use not existing class or ' .
1009
+								'interface "%s".',
1010
+								$className
1011
+							)
1012
+						);
1013
+					}
1014
+
1015
+					$class   = new ReflectionClass($className);
1016
+					$methods = $class->getMethods();
1017
+					$inverse = isset($methodName[1]) && $methodName[1] == '!';
1018
+
1019
+					if (\strpos($methodName, 'protected')) {
1020
+						$visibility = 'isProtected';
1021
+					} elseif (\strpos($methodName, 'private')) {
1022
+						$visibility = 'isPrivate';
1023
+					} elseif (\strpos($methodName, 'public')) {
1024
+						$visibility = 'isPublic';
1025
+					}
1026
+
1027
+					foreach ($methods as $method) {
1028
+						if ($inverse && !$method->$visibility()) {
1029
+							$codeToCoverList[] = $method;
1030
+						} elseif (!$inverse && $method->$visibility()) {
1031
+							$codeToCoverList[] = $method;
1032
+						}
1033
+					}
1034
+				}
1035
+			} else {
1036
+				$classes = [$className];
1037
+
1038
+				foreach ($classes as $className) {
1039
+					if ($className == '' && \function_exists($methodName)) {
1040
+						$codeToCoverList[] = new ReflectionFunction(
1041
+							$methodName
1042
+						);
1043
+					} else {
1044
+						if (!((\class_exists($className) || \interface_exists($className) || \trait_exists($className)) &&
1045
+							\method_exists($className, $methodName))) {
1046
+							throw new InvalidCoversTargetException(
1047
+								\sprintf(
1048
+									'Trying to @cover or @use not existing method "%s::%s".',
1049
+									$className,
1050
+									$methodName
1051
+								)
1052
+							);
1053
+						}
1054
+
1055
+						$codeToCoverList[] = new ReflectionMethod(
1056
+							$className,
1057
+							$methodName
1058
+						);
1059
+					}
1060
+				}
1061
+			}
1062
+		} else {
1063
+			$extended = false;
1064
+
1065
+			if (\strpos($element, '<extended>') !== false) {
1066
+				$element  = \str_replace('<extended>', '', $element);
1067
+				$extended = true;
1068
+			}
1069
+
1070
+			$classes = [$element];
1071
+
1072
+			if ($extended) {
1073
+				$classes = \array_merge(
1074
+					$classes,
1075
+					\class_implements($element),
1076
+					\class_parents($element)
1077
+				);
1078
+			}
1079
+
1080
+			foreach ($classes as $className) {
1081
+				if (!\class_exists($className) &&
1082
+					!\interface_exists($className) &&
1083
+					!\trait_exists($className)) {
1084
+					throw new InvalidCoversTargetException(
1085
+						\sprintf(
1086
+							'Trying to @cover or @use not existing class or ' .
1087
+							'interface "%s".',
1088
+							$className
1089
+						)
1090
+					);
1091
+				}
1092
+
1093
+				$codeToCoverList[] = new ReflectionClass($className);
1094
+			}
1095
+		}
1096
+
1097
+		return $codeToCoverList;
1098
+	}
1099
+
1100
+	/**
1101
+	 * @param array $reflectors
1102
+	 *
1103
+	 * @return array
1104
+	 */
1105
+	private static function resolveReflectionObjectsToLines(array $reflectors)
1106
+	{
1107
+		$result = [];
1108
+
1109
+		foreach ($reflectors as $reflector) {
1110
+			$filename = $reflector->getFileName();
1111
+
1112
+			if (!isset($result[$filename])) {
1113
+				$result[$filename] = [];
1114
+			}
1115
+
1116
+			$result[$filename] = \array_merge(
1117
+				$result[$filename],
1118
+				\range($reflector->getStartLine(), $reflector->getEndLine())
1119
+			);
1120
+		}
1121
+
1122
+		foreach ($result as $filename => $lineNumbers) {
1123
+			$result[$filename] = \array_keys(\array_flip($lineNumbers));
1124
+		}
1125
+
1126
+		return $result;
1127
+	}
1128
+
1129
+	/**
1130
+	 * @param ReflectionMethod $method
1131
+	 *
1132
+	 * @return bool
1133
+	 */
1134
+	private static function isBeforeClassMethod(ReflectionMethod $method)
1135
+	{
1136
+		return $method->isStatic() && \strpos($method->getDocComment(), '@beforeClass') !== false;
1137
+	}
1138
+
1139
+	/**
1140
+	 * @param ReflectionMethod $method
1141
+	 *
1142
+	 * @return bool
1143
+	 */
1144
+	private static function isBeforeMethod(ReflectionMethod $method)
1145
+	{
1146
+		return \preg_match('/@before\b/', $method->getDocComment()) > 0;
1147
+	}
1148
+
1149
+	/**
1150
+	 * @param ReflectionMethod $method
1151
+	 *
1152
+	 * @return bool
1153
+	 */
1154
+	private static function isAfterClassMethod(ReflectionMethod $method)
1155
+	{
1156
+		return $method->isStatic() && \strpos($method->getDocComment(), '@afterClass') !== false;
1157
+	}
1158
+
1159
+	/**
1160
+	 * @param ReflectionMethod $method
1161
+	 *
1162
+	 * @return bool
1163
+	 */
1164
+	private static function isAfterMethod(ReflectionMethod $method)
1165
+	{
1166
+		return \preg_match('/@after\b/', $method->getDocComment()) > 0;
1167
+	}
1168
+
1169
+	/**
1170
+	 * Trims any extensions from version string that follows after
1171
+	 * the <major>.<minor>[.<patch>] format
1172
+	 *
1173
+	 * @param $version (Optional)
1174
+	 *
1175
+	 * @return mixed
1176
+	 */
1177
+	private static function sanitizeVersionNumber($version)
1178
+	{
1179
+		return \preg_replace(
1180
+			'/^(\d+\.\d+(?:.\d+)?).*$/',
1181
+			'$1',
1182
+			$version
1183
+		);
1184
+	}
1185 1185
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/src/Util/Log/JUnit.php 1 patch
Indentation   +415 added lines, -415 removed lines patch added patch discarded remove patch
@@ -33,419 +33,419 @@
 block discarded – undo
33 33
  */
34 34
 class JUnit extends Printer implements TestListener
35 35
 {
36
-    /**
37
-     * @var DOMDocument
38
-     */
39
-    protected $document;
40
-
41
-    /**
42
-     * @var DOMElement
43
-     */
44
-    protected $root;
45
-
46
-    /**
47
-     * @var bool
48
-     */
49
-    protected $reportUselessTests = false;
50
-
51
-    /**
52
-     * @var bool
53
-     */
54
-    protected $writeDocument = true;
55
-
56
-    /**
57
-     * @var DOMElement[]
58
-     */
59
-    protected $testSuites = [];
60
-
61
-    /**
62
-     * @var int[]
63
-     */
64
-    protected $testSuiteTests = [0];
65
-
66
-    /**
67
-     * @var int[]
68
-     */
69
-    protected $testSuiteAssertions = [0];
70
-
71
-    /**
72
-     * @var int[]
73
-     */
74
-    protected $testSuiteErrors = [0];
75
-
76
-    /**
77
-     * @var int[]
78
-     */
79
-    protected $testSuiteFailures = [0];
80
-
81
-    /**
82
-     * @var int[]
83
-     */
84
-    protected $testSuiteSkipped = [0];
85
-
86
-    /**
87
-     * @var int[]
88
-     */
89
-    protected $testSuiteTimes = [0];
90
-
91
-    /**
92
-     * @var int
93
-     */
94
-    protected $testSuiteLevel = 0;
95
-
96
-    /**
97
-     * @var ?DOMElement
98
-     */
99
-    protected $currentTestCase;
100
-
101
-    /**
102
-     * Constructor.
103
-     *
104
-     * @param mixed $out
105
-     * @param bool  $reportUselessTests
106
-     */
107
-    public function __construct($out = null, $reportUselessTests = false)
108
-    {
109
-        $this->document               = new DOMDocument('1.0', 'UTF-8');
110
-        $this->document->formatOutput = true;
111
-
112
-        $this->root = $this->document->createElement('testsuites');
113
-        $this->document->appendChild($this->root);
114
-
115
-        parent::__construct($out);
116
-
117
-        $this->reportUselessTests = $reportUselessTests;
118
-    }
119
-
120
-    /**
121
-     * Flush buffer and close output.
122
-     */
123
-    public function flush()
124
-    {
125
-        if ($this->writeDocument === true) {
126
-            $this->write($this->getXML());
127
-        }
128
-
129
-        parent::flush();
130
-    }
131
-
132
-    /**
133
-     * An error occurred.
134
-     *
135
-     * @param Test       $test
136
-     * @param \Exception $e
137
-     * @param float      $time
138
-     */
139
-    public function addError(Test $test, \Exception $e, $time)
140
-    {
141
-        $this->doAddFault($test, $e, $time, 'error');
142
-        $this->testSuiteErrors[$this->testSuiteLevel]++;
143
-    }
144
-
145
-    /**
146
-     * A warning occurred.
147
-     *
148
-     * @param Test    $test
149
-     * @param Warning $e
150
-     * @param float   $time
151
-     */
152
-    public function addWarning(Test $test, Warning $e, $time)
153
-    {
154
-        $this->doAddFault($test, $e, $time, 'warning');
155
-        $this->testSuiteFailures[$this->testSuiteLevel]++;
156
-    }
157
-
158
-    /**
159
-     * A failure occurred.
160
-     *
161
-     * @param Test                 $test
162
-     * @param AssertionFailedError $e
163
-     * @param float                $time
164
-     */
165
-    public function addFailure(Test $test, AssertionFailedError $e, $time)
166
-    {
167
-        $this->doAddFault($test, $e, $time, 'failure');
168
-        $this->testSuiteFailures[$this->testSuiteLevel]++;
169
-    }
170
-
171
-    /**
172
-     * Incomplete test.
173
-     *
174
-     * @param Test       $test
175
-     * @param \Exception $e
176
-     * @param float      $time
177
-     */
178
-    public function addIncompleteTest(Test $test, \Exception $e, $time)
179
-    {
180
-        $this->doAddSkipped($test);
181
-    }
182
-
183
-    /**
184
-     * Risky test.
185
-     *
186
-     * @param Test       $test
187
-     * @param \Exception $e
188
-     * @param float      $time
189
-     */
190
-    public function addRiskyTest(Test $test, \Exception $e, $time)
191
-    {
192
-        if (!$this->reportUselessTests || $this->currentTestCase === null) {
193
-            return;
194
-        }
195
-
196
-        $error = $this->document->createElement(
197
-            'error',
198
-            Xml::prepareString(
199
-                "Risky Test\n" .
200
-                Filter::getFilteredStacktrace($e)
201
-            )
202
-        );
203
-
204
-        $error->setAttribute('type', \get_class($e));
205
-
206
-        $this->currentTestCase->appendChild($error);
207
-
208
-        $this->testSuiteErrors[$this->testSuiteLevel]++;
209
-    }
210
-
211
-    /**
212
-     * Skipped test.
213
-     *
214
-     * @param Test       $test
215
-     * @param \Exception $e
216
-     * @param float      $time
217
-     */
218
-    public function addSkippedTest(Test $test, \Exception $e, $time)
219
-    {
220
-        $this->doAddSkipped($test);
221
-    }
222
-
223
-    /**
224
-     * A testsuite started.
225
-     *
226
-     * @param TestSuite $suite
227
-     */
228
-    public function startTestSuite(TestSuite $suite)
229
-    {
230
-        $testSuite = $this->document->createElement('testsuite');
231
-        $testSuite->setAttribute('name', $suite->getName());
232
-
233
-        if (\class_exists($suite->getName(), false)) {
234
-            try {
235
-                $class = new ReflectionClass($suite->getName());
236
-
237
-                $testSuite->setAttribute('file', $class->getFileName());
238
-            } catch (ReflectionException $e) {
239
-            }
240
-        }
241
-
242
-        if ($this->testSuiteLevel > 0) {
243
-            $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
244
-        } else {
245
-            $this->root->appendChild($testSuite);
246
-        }
247
-
248
-        $this->testSuiteLevel++;
249
-        $this->testSuites[$this->testSuiteLevel]          = $testSuite;
250
-        $this->testSuiteTests[$this->testSuiteLevel]      = 0;
251
-        $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
252
-        $this->testSuiteErrors[$this->testSuiteLevel]     = 0;
253
-        $this->testSuiteFailures[$this->testSuiteLevel]   = 0;
254
-        $this->testSuiteSkipped[$this->testSuiteLevel]    = 0;
255
-        $this->testSuiteTimes[$this->testSuiteLevel]      = 0;
256
-    }
257
-
258
-    /**
259
-     * A testsuite ended.
260
-     *
261
-     * @param TestSuite $suite
262
-     */
263
-    public function endTestSuite(TestSuite $suite)
264
-    {
265
-        $this->testSuites[$this->testSuiteLevel]->setAttribute(
266
-            'tests',
267
-            $this->testSuiteTests[$this->testSuiteLevel]
268
-        );
269
-
270
-        $this->testSuites[$this->testSuiteLevel]->setAttribute(
271
-            'assertions',
272
-            $this->testSuiteAssertions[$this->testSuiteLevel]
273
-        );
274
-
275
-        $this->testSuites[$this->testSuiteLevel]->setAttribute(
276
-            'errors',
277
-            $this->testSuiteErrors[$this->testSuiteLevel]
278
-        );
279
-
280
-        $this->testSuites[$this->testSuiteLevel]->setAttribute(
281
-            'failures',
282
-            $this->testSuiteFailures[$this->testSuiteLevel]
283
-        );
284
-
285
-        $this->testSuites[$this->testSuiteLevel]->setAttribute(
286
-            'skipped',
287
-            $this->testSuiteSkipped[$this->testSuiteLevel]
288
-        );
289
-
290
-        $this->testSuites[$this->testSuiteLevel]->setAttribute(
291
-            'time',
292
-            \sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel])
293
-        );
294
-
295
-        if ($this->testSuiteLevel > 1) {
296
-            $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
297
-            $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
298
-            $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
299
-            $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
300
-            $this->testSuiteSkipped[$this->testSuiteLevel - 1] += $this->testSuiteSkipped[$this->testSuiteLevel];
301
-            $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
302
-        }
303
-
304
-        $this->testSuiteLevel--;
305
-    }
306
-
307
-    /**
308
-     * A test started.
309
-     *
310
-     * @param Test $test
311
-     */
312
-    public function startTest(Test $test)
313
-    {
314
-        $testCase = $this->document->createElement('testcase');
315
-        $testCase->setAttribute('name', $test->getName());
316
-
317
-        if ($test instanceof TestCase) {
318
-            $class      = new ReflectionClass($test);
319
-            $methodName = $test->getName(!$test->usesDataProvider());
320
-
321
-            if ($class->hasMethod($methodName)) {
322
-                $method = $class->getMethod($methodName);
323
-
324
-                $testCase->setAttribute('class', $class->getName());
325
-                $testCase->setAttribute('classname', \str_replace('\\', '.', $class->getName()));
326
-                $testCase->setAttribute('file', $class->getFileName());
327
-                $testCase->setAttribute('line', $method->getStartLine());
328
-            }
329
-        }
330
-
331
-        $this->currentTestCase = $testCase;
332
-    }
333
-
334
-    /**
335
-     * A test ended.
336
-     *
337
-     * @param Test  $test
338
-     * @param float $time
339
-     */
340
-    public function endTest(Test $test, $time)
341
-    {
342
-        if ($test instanceof TestCase) {
343
-            $numAssertions = $test->getNumAssertions();
344
-            $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions;
345
-
346
-            $this->currentTestCase->setAttribute(
347
-                'assertions',
348
-                $numAssertions
349
-            );
350
-        }
351
-
352
-        $this->currentTestCase->setAttribute(
353
-            'time',
354
-            \sprintf('%F', $time)
355
-        );
356
-
357
-        $this->testSuites[$this->testSuiteLevel]->appendChild(
358
-            $this->currentTestCase
359
-        );
360
-
361
-        $this->testSuiteTests[$this->testSuiteLevel]++;
362
-        $this->testSuiteTimes[$this->testSuiteLevel] += $time;
363
-
364
-        if (\method_exists($test, 'hasOutput') && $test->hasOutput()) {
365
-            $systemOut = $this->document->createElement('system-out');
366
-
367
-            $systemOut->appendChild(
368
-                $this->document->createTextNode($test->getActualOutput())
369
-            );
370
-
371
-            $this->currentTestCase->appendChild($systemOut);
372
-        }
373
-
374
-        $this->currentTestCase = null;
375
-    }
376
-
377
-    /**
378
-     * Returns the XML as a string.
379
-     *
380
-     * @return string
381
-     */
382
-    public function getXML()
383
-    {
384
-        return $this->document->saveXML();
385
-    }
386
-
387
-    /**
388
-     * Enables or disables the writing of the document
389
-     * in flush().
390
-     *
391
-     * This is a "hack" needed for the integration of
392
-     * PHPUnit with Phing.
393
-     *
394
-     * @return string
395
-     */
396
-    public function setWriteDocument($flag)
397
-    {
398
-        if (\is_bool($flag)) {
399
-            $this->writeDocument = $flag;
400
-        }
401
-    }
402
-
403
-    /**
404
-     * Method which generalizes addError() and addFailure()
405
-     *
406
-     * @param Test       $test
407
-     * @param \Exception $e
408
-     * @param float      $time
409
-     * @param string     $type
410
-     */
411
-    private function doAddFault(Test $test, \Exception $e, $time, $type)
412
-    {
413
-        if ($this->currentTestCase === null) {
414
-            return;
415
-        }
416
-
417
-        if ($test instanceof SelfDescribing) {
418
-            $buffer = $test->toString() . "\n";
419
-        } else {
420
-            $buffer = '';
421
-        }
422
-
423
-        $buffer .= TestFailure::exceptionToString($e) . "\n" .
424
-                   Filter::getFilteredStacktrace($e);
425
-
426
-        $fault = $this->document->createElement(
427
-            $type,
428
-            Xml::prepareString($buffer)
429
-        );
430
-
431
-        if ($e instanceof ExceptionWrapper) {
432
-            $fault->setAttribute('type', $e->getClassName());
433
-        } else {
434
-            $fault->setAttribute('type', \get_class($e));
435
-        }
436
-
437
-        $this->currentTestCase->appendChild($fault);
438
-    }
439
-
440
-    private function doAddSkipped(Test $test)
441
-    {
442
-        if ($this->currentTestCase === null) {
443
-            return;
444
-        }
445
-
446
-        $skipped = $this->document->createElement('skipped');
447
-        $this->currentTestCase->appendChild($skipped);
448
-
449
-        $this->testSuiteSkipped[$this->testSuiteLevel]++;
450
-    }
36
+	/**
37
+	 * @var DOMDocument
38
+	 */
39
+	protected $document;
40
+
41
+	/**
42
+	 * @var DOMElement
43
+	 */
44
+	protected $root;
45
+
46
+	/**
47
+	 * @var bool
48
+	 */
49
+	protected $reportUselessTests = false;
50
+
51
+	/**
52
+	 * @var bool
53
+	 */
54
+	protected $writeDocument = true;
55
+
56
+	/**
57
+	 * @var DOMElement[]
58
+	 */
59
+	protected $testSuites = [];
60
+
61
+	/**
62
+	 * @var int[]
63
+	 */
64
+	protected $testSuiteTests = [0];
65
+
66
+	/**
67
+	 * @var int[]
68
+	 */
69
+	protected $testSuiteAssertions = [0];
70
+
71
+	/**
72
+	 * @var int[]
73
+	 */
74
+	protected $testSuiteErrors = [0];
75
+
76
+	/**
77
+	 * @var int[]
78
+	 */
79
+	protected $testSuiteFailures = [0];
80
+
81
+	/**
82
+	 * @var int[]
83
+	 */
84
+	protected $testSuiteSkipped = [0];
85
+
86
+	/**
87
+	 * @var int[]
88
+	 */
89
+	protected $testSuiteTimes = [0];
90
+
91
+	/**
92
+	 * @var int
93
+	 */
94
+	protected $testSuiteLevel = 0;
95
+
96
+	/**
97
+	 * @var ?DOMElement
98
+	 */
99
+	protected $currentTestCase;
100
+
101
+	/**
102
+	 * Constructor.
103
+	 *
104
+	 * @param mixed $out
105
+	 * @param bool  $reportUselessTests
106
+	 */
107
+	public function __construct($out = null, $reportUselessTests = false)
108
+	{
109
+		$this->document               = new DOMDocument('1.0', 'UTF-8');
110
+		$this->document->formatOutput = true;
111
+
112
+		$this->root = $this->document->createElement('testsuites');
113
+		$this->document->appendChild($this->root);
114
+
115
+		parent::__construct($out);
116
+
117
+		$this->reportUselessTests = $reportUselessTests;
118
+	}
119
+
120
+	/**
121
+	 * Flush buffer and close output.
122
+	 */
123
+	public function flush()
124
+	{
125
+		if ($this->writeDocument === true) {
126
+			$this->write($this->getXML());
127
+		}
128
+
129
+		parent::flush();
130
+	}
131
+
132
+	/**
133
+	 * An error occurred.
134
+	 *
135
+	 * @param Test       $test
136
+	 * @param \Exception $e
137
+	 * @param float      $time
138
+	 */
139
+	public function addError(Test $test, \Exception $e, $time)
140
+	{
141
+		$this->doAddFault($test, $e, $time, 'error');
142
+		$this->testSuiteErrors[$this->testSuiteLevel]++;
143
+	}
144
+
145
+	/**
146
+	 * A warning occurred.
147
+	 *
148
+	 * @param Test    $test
149
+	 * @param Warning $e
150
+	 * @param float   $time
151
+	 */
152
+	public function addWarning(Test $test, Warning $e, $time)
153
+	{
154
+		$this->doAddFault($test, $e, $time, 'warning');
155
+		$this->testSuiteFailures[$this->testSuiteLevel]++;
156
+	}
157
+
158
+	/**
159
+	 * A failure occurred.
160
+	 *
161
+	 * @param Test                 $test
162
+	 * @param AssertionFailedError $e
163
+	 * @param float                $time
164
+	 */
165
+	public function addFailure(Test $test, AssertionFailedError $e, $time)
166
+	{
167
+		$this->doAddFault($test, $e, $time, 'failure');
168
+		$this->testSuiteFailures[$this->testSuiteLevel]++;
169
+	}
170
+
171
+	/**
172
+	 * Incomplete test.
173
+	 *
174
+	 * @param Test       $test
175
+	 * @param \Exception $e
176
+	 * @param float      $time
177
+	 */
178
+	public function addIncompleteTest(Test $test, \Exception $e, $time)
179
+	{
180
+		$this->doAddSkipped($test);
181
+	}
182
+
183
+	/**
184
+	 * Risky test.
185
+	 *
186
+	 * @param Test       $test
187
+	 * @param \Exception $e
188
+	 * @param float      $time
189
+	 */
190
+	public function addRiskyTest(Test $test, \Exception $e, $time)
191
+	{
192
+		if (!$this->reportUselessTests || $this->currentTestCase === null) {
193
+			return;
194
+		}
195
+
196
+		$error = $this->document->createElement(
197
+			'error',
198
+			Xml::prepareString(
199
+				"Risky Test\n" .
200
+				Filter::getFilteredStacktrace($e)
201
+			)
202
+		);
203
+
204
+		$error->setAttribute('type', \get_class($e));
205
+
206
+		$this->currentTestCase->appendChild($error);
207
+
208
+		$this->testSuiteErrors[$this->testSuiteLevel]++;
209
+	}
210
+
211
+	/**
212
+	 * Skipped test.
213
+	 *
214
+	 * @param Test       $test
215
+	 * @param \Exception $e
216
+	 * @param float      $time
217
+	 */
218
+	public function addSkippedTest(Test $test, \Exception $e, $time)
219
+	{
220
+		$this->doAddSkipped($test);
221
+	}
222
+
223
+	/**
224
+	 * A testsuite started.
225
+	 *
226
+	 * @param TestSuite $suite
227
+	 */
228
+	public function startTestSuite(TestSuite $suite)
229
+	{
230
+		$testSuite = $this->document->createElement('testsuite');
231
+		$testSuite->setAttribute('name', $suite->getName());
232
+
233
+		if (\class_exists($suite->getName(), false)) {
234
+			try {
235
+				$class = new ReflectionClass($suite->getName());
236
+
237
+				$testSuite->setAttribute('file', $class->getFileName());
238
+			} catch (ReflectionException $e) {
239
+			}
240
+		}
241
+
242
+		if ($this->testSuiteLevel > 0) {
243
+			$this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
244
+		} else {
245
+			$this->root->appendChild($testSuite);
246
+		}
247
+
248
+		$this->testSuiteLevel++;
249
+		$this->testSuites[$this->testSuiteLevel]          = $testSuite;
250
+		$this->testSuiteTests[$this->testSuiteLevel]      = 0;
251
+		$this->testSuiteAssertions[$this->testSuiteLevel] = 0;
252
+		$this->testSuiteErrors[$this->testSuiteLevel]     = 0;
253
+		$this->testSuiteFailures[$this->testSuiteLevel]   = 0;
254
+		$this->testSuiteSkipped[$this->testSuiteLevel]    = 0;
255
+		$this->testSuiteTimes[$this->testSuiteLevel]      = 0;
256
+	}
257
+
258
+	/**
259
+	 * A testsuite ended.
260
+	 *
261
+	 * @param TestSuite $suite
262
+	 */
263
+	public function endTestSuite(TestSuite $suite)
264
+	{
265
+		$this->testSuites[$this->testSuiteLevel]->setAttribute(
266
+			'tests',
267
+			$this->testSuiteTests[$this->testSuiteLevel]
268
+		);
269
+
270
+		$this->testSuites[$this->testSuiteLevel]->setAttribute(
271
+			'assertions',
272
+			$this->testSuiteAssertions[$this->testSuiteLevel]
273
+		);
274
+
275
+		$this->testSuites[$this->testSuiteLevel]->setAttribute(
276
+			'errors',
277
+			$this->testSuiteErrors[$this->testSuiteLevel]
278
+		);
279
+
280
+		$this->testSuites[$this->testSuiteLevel]->setAttribute(
281
+			'failures',
282
+			$this->testSuiteFailures[$this->testSuiteLevel]
283
+		);
284
+
285
+		$this->testSuites[$this->testSuiteLevel]->setAttribute(
286
+			'skipped',
287
+			$this->testSuiteSkipped[$this->testSuiteLevel]
288
+		);
289
+
290
+		$this->testSuites[$this->testSuiteLevel]->setAttribute(
291
+			'time',
292
+			\sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel])
293
+		);
294
+
295
+		if ($this->testSuiteLevel > 1) {
296
+			$this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
297
+			$this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
298
+			$this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
299
+			$this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
300
+			$this->testSuiteSkipped[$this->testSuiteLevel - 1] += $this->testSuiteSkipped[$this->testSuiteLevel];
301
+			$this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
302
+		}
303
+
304
+		$this->testSuiteLevel--;
305
+	}
306
+
307
+	/**
308
+	 * A test started.
309
+	 *
310
+	 * @param Test $test
311
+	 */
312
+	public function startTest(Test $test)
313
+	{
314
+		$testCase = $this->document->createElement('testcase');
315
+		$testCase->setAttribute('name', $test->getName());
316
+
317
+		if ($test instanceof TestCase) {
318
+			$class      = new ReflectionClass($test);
319
+			$methodName = $test->getName(!$test->usesDataProvider());
320
+
321
+			if ($class->hasMethod($methodName)) {
322
+				$method = $class->getMethod($methodName);
323
+
324
+				$testCase->setAttribute('class', $class->getName());
325
+				$testCase->setAttribute('classname', \str_replace('\\', '.', $class->getName()));
326
+				$testCase->setAttribute('file', $class->getFileName());
327
+				$testCase->setAttribute('line', $method->getStartLine());
328
+			}
329
+		}
330
+
331
+		$this->currentTestCase = $testCase;
332
+	}
333
+
334
+	/**
335
+	 * A test ended.
336
+	 *
337
+	 * @param Test  $test
338
+	 * @param float $time
339
+	 */
340
+	public function endTest(Test $test, $time)
341
+	{
342
+		if ($test instanceof TestCase) {
343
+			$numAssertions = $test->getNumAssertions();
344
+			$this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions;
345
+
346
+			$this->currentTestCase->setAttribute(
347
+				'assertions',
348
+				$numAssertions
349
+			);
350
+		}
351
+
352
+		$this->currentTestCase->setAttribute(
353
+			'time',
354
+			\sprintf('%F', $time)
355
+		);
356
+
357
+		$this->testSuites[$this->testSuiteLevel]->appendChild(
358
+			$this->currentTestCase
359
+		);
360
+
361
+		$this->testSuiteTests[$this->testSuiteLevel]++;
362
+		$this->testSuiteTimes[$this->testSuiteLevel] += $time;
363
+
364
+		if (\method_exists($test, 'hasOutput') && $test->hasOutput()) {
365
+			$systemOut = $this->document->createElement('system-out');
366
+
367
+			$systemOut->appendChild(
368
+				$this->document->createTextNode($test->getActualOutput())
369
+			);
370
+
371
+			$this->currentTestCase->appendChild($systemOut);
372
+		}
373
+
374
+		$this->currentTestCase = null;
375
+	}
376
+
377
+	/**
378
+	 * Returns the XML as a string.
379
+	 *
380
+	 * @return string
381
+	 */
382
+	public function getXML()
383
+	{
384
+		return $this->document->saveXML();
385
+	}
386
+
387
+	/**
388
+	 * Enables or disables the writing of the document
389
+	 * in flush().
390
+	 *
391
+	 * This is a "hack" needed for the integration of
392
+	 * PHPUnit with Phing.
393
+	 *
394
+	 * @return string
395
+	 */
396
+	public function setWriteDocument($flag)
397
+	{
398
+		if (\is_bool($flag)) {
399
+			$this->writeDocument = $flag;
400
+		}
401
+	}
402
+
403
+	/**
404
+	 * Method which generalizes addError() and addFailure()
405
+	 *
406
+	 * @param Test       $test
407
+	 * @param \Exception $e
408
+	 * @param float      $time
409
+	 * @param string     $type
410
+	 */
411
+	private function doAddFault(Test $test, \Exception $e, $time, $type)
412
+	{
413
+		if ($this->currentTestCase === null) {
414
+			return;
415
+		}
416
+
417
+		if ($test instanceof SelfDescribing) {
418
+			$buffer = $test->toString() . "\n";
419
+		} else {
420
+			$buffer = '';
421
+		}
422
+
423
+		$buffer .= TestFailure::exceptionToString($e) . "\n" .
424
+				   Filter::getFilteredStacktrace($e);
425
+
426
+		$fault = $this->document->createElement(
427
+			$type,
428
+			Xml::prepareString($buffer)
429
+		);
430
+
431
+		if ($e instanceof ExceptionWrapper) {
432
+			$fault->setAttribute('type', $e->getClassName());
433
+		} else {
434
+			$fault->setAttribute('type', \get_class($e));
435
+		}
436
+
437
+		$this->currentTestCase->appendChild($fault);
438
+	}
439
+
440
+	private function doAddSkipped(Test $test)
441
+	{
442
+		if ($this->currentTestCase === null) {
443
+			return;
444
+		}
445
+
446
+		$skipped = $this->document->createElement('skipped');
447
+		$this->currentTestCase->appendChild($skipped);
448
+
449
+		$this->testSuiteSkipped[$this->testSuiteLevel]++;
450
+	}
451 451
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/src/Util/Log/TeamCity.php 1 patch
Indentation   +390 added lines, -390 removed lines patch added patch discarded remove patch
@@ -31,394 +31,394 @@
 block discarded – undo
31 31
  */
32 32
 class TeamCity extends ResultPrinter
33 33
 {
34
-    /**
35
-     * @var bool
36
-     */
37
-    private $isSummaryTestCountPrinted = false;
38
-
39
-    /**
40
-     * @var string
41
-     */
42
-    private $startedTestName;
43
-
44
-    /**
45
-     * @var int|false
46
-     */
47
-    private $flowId;
48
-
49
-    /**
50
-     * @param string $progress
51
-     */
52
-    protected function writeProgress($progress)
53
-    {
54
-    }
55
-
56
-    /**
57
-     * @param TestResult $result
58
-     */
59
-    public function printResult(TestResult $result)
60
-    {
61
-        $this->printHeader();
62
-        $this->printFooter($result);
63
-    }
64
-
65
-    /**
66
-     * An error occurred.
67
-     *
68
-     * @param Test       $test
69
-     * @param \Exception $e
70
-     * @param float      $time
71
-     */
72
-    public function addError(Test $test, \Exception $e, $time)
73
-    {
74
-        $this->printEvent(
75
-            'testFailed',
76
-            [
77
-                'name'    => $test->getName(),
78
-                'message' => self::getMessage($e),
79
-                'details' => self::getDetails($e),
80
-            ]
81
-        );
82
-    }
83
-
84
-    /**
85
-     * A warning occurred.
86
-     *
87
-     * @param Test    $test
88
-     * @param Warning $e
89
-     * @param float   $time
90
-     */
91
-    public function addWarning(Test $test, Warning $e, $time)
92
-    {
93
-        $this->printEvent(
94
-            'testFailed',
95
-            [
96
-                'name'    => $test->getName(),
97
-                'message' => self::getMessage($e),
98
-                'details' => self::getDetails($e)
99
-            ]
100
-        );
101
-    }
102
-
103
-    /**
104
-     * A failure occurred.
105
-     *
106
-     * @param Test                 $test
107
-     * @param AssertionFailedError $e
108
-     * @param float                $time
109
-     */
110
-    public function addFailure(Test $test, AssertionFailedError $e, $time)
111
-    {
112
-        $parameters = [
113
-            'name'    => $test->getName(),
114
-            'message' => self::getMessage($e),
115
-            'details' => self::getDetails($e),
116
-        ];
117
-
118
-        if ($e instanceof ExpectationFailedException) {
119
-            $comparisonFailure = $e->getComparisonFailure();
120
-
121
-            if ($comparisonFailure instanceof ComparisonFailure) {
122
-                $expectedString = $comparisonFailure->getExpectedAsString();
123
-
124
-                if (null === $expectedString || empty($expectedString)) {
125
-                    $expectedString = self::getPrimitiveValueAsString($comparisonFailure->getExpected());
126
-                }
127
-
128
-                $actualString = $comparisonFailure->getActualAsString();
129
-
130
-                if (null === $actualString || empty($actualString)) {
131
-                    $actualString = self::getPrimitiveValueAsString($comparisonFailure->getActual());
132
-                }
133
-
134
-                if (null !== $actualString && null !== $expectedString) {
135
-                    $parameters['type']     = 'comparisonFailure';
136
-                    $parameters['actual']   = $actualString;
137
-                    $parameters['expected'] = $expectedString;
138
-                }
139
-            }
140
-        }
141
-
142
-        $this->printEvent('testFailed', $parameters);
143
-    }
144
-
145
-    /**
146
-     * Incomplete test.
147
-     *
148
-     * @param Test       $test
149
-     * @param \Exception $e
150
-     * @param float      $time
151
-     */
152
-    public function addIncompleteTest(Test $test, \Exception $e, $time)
153
-    {
154
-        $this->printIgnoredTest($test->getName(), $e);
155
-    }
156
-
157
-    /**
158
-     * Risky test.
159
-     *
160
-     * @param Test       $test
161
-     * @param \Exception $e
162
-     * @param float      $time
163
-     */
164
-    public function addRiskyTest(Test $test, \Exception $e, $time)
165
-    {
166
-        $this->addError($test, $e, $time);
167
-    }
168
-
169
-    /**
170
-     * Skipped test.
171
-     *
172
-     * @param Test       $test
173
-     * @param \Exception $e
174
-     * @param float      $time
175
-     */
176
-    public function addSkippedTest(Test $test, \Exception $e, $time)
177
-    {
178
-        $testName = $test->getName();
179
-        if ($this->startedTestName != $testName) {
180
-            $this->startTest($test);
181
-            $this->printIgnoredTest($testName, $e);
182
-            $this->endTest($test, $time);
183
-        } else {
184
-            $this->printIgnoredTest($testName, $e);
185
-        }
186
-    }
187
-
188
-    public function printIgnoredTest($testName, \Exception $e)
189
-    {
190
-        $this->printEvent(
191
-            'testIgnored',
192
-            [
193
-                'name'    => $testName,
194
-                'message' => self::getMessage($e),
195
-                'details' => self::getDetails($e),
196
-            ]
197
-        );
198
-    }
199
-
200
-    /**
201
-     * A testsuite started.
202
-     *
203
-     * @param TestSuite $suite
204
-     */
205
-    public function startTestSuite(TestSuite $suite)
206
-    {
207
-        if (\stripos(\ini_get('disable_functions'), 'getmypid') === false) {
208
-            $this->flowId = \getmypid();
209
-        } else {
210
-            $this->flowId = false;
211
-        }
212
-
213
-        if (!$this->isSummaryTestCountPrinted) {
214
-            $this->isSummaryTestCountPrinted = true;
215
-
216
-            $this->printEvent(
217
-                'testCount',
218
-                ['count' => \count($suite)]
219
-            );
220
-        }
221
-
222
-        $suiteName = $suite->getName();
223
-
224
-        if (empty($suiteName)) {
225
-            return;
226
-        }
227
-
228
-        $parameters = ['name' => $suiteName];
229
-
230
-        if (\class_exists($suiteName, false)) {
231
-            $fileName                   = self::getFileName($suiteName);
232
-            $parameters['locationHint'] = "php_qn://$fileName::\\$suiteName";
233
-        } else {
234
-            $split = \preg_split('/::/', $suiteName);
235
-
236
-            if (\count($split) == 2 && \method_exists($split[0], $split[1])) {
237
-                $fileName                   = self::getFileName($split[0]);
238
-                $parameters['locationHint'] = "php_qn://$fileName::\\$suiteName";
239
-                $parameters['name']         = $split[1];
240
-            }
241
-        }
242
-
243
-        $this->printEvent('testSuiteStarted', $parameters);
244
-    }
245
-
246
-    /**
247
-     * A testsuite ended.
248
-     *
249
-     * @param TestSuite $suite
250
-     */
251
-    public function endTestSuite(TestSuite $suite)
252
-    {
253
-        $suiteName = $suite->getName();
254
-
255
-        if (empty($suiteName)) {
256
-            return;
257
-        }
258
-
259
-        $parameters = ['name' => $suiteName];
260
-
261
-        if (!\class_exists($suiteName, false)) {
262
-            $split = \preg_split('/::/', $suiteName);
263
-
264
-            if (\count($split) == 2 && \method_exists($split[0], $split[1])) {
265
-                $parameters['name'] = $split[1];
266
-            }
267
-        }
268
-
269
-        $this->printEvent('testSuiteFinished', $parameters);
270
-    }
271
-
272
-    /**
273
-     * A test started.
274
-     *
275
-     * @param Test $test
276
-     */
277
-    public function startTest(Test $test)
278
-    {
279
-        $testName              = $test->getName();
280
-        $this->startedTestName = $testName;
281
-        $params                = ['name' => $testName];
282
-
283
-        if ($test instanceof TestCase) {
284
-            $className              = \get_class($test);
285
-            $fileName               = self::getFileName($className);
286
-            $params['locationHint'] = "php_qn://$fileName::\\$className::$testName";
287
-        }
288
-
289
-        $this->printEvent('testStarted', $params);
290
-    }
291
-
292
-    /**
293
-     * A test ended.
294
-     *
295
-     * @param Test  $test
296
-     * @param float $time
297
-     */
298
-    public function endTest(Test $test, $time)
299
-    {
300
-        parent::endTest($test, $time);
301
-
302
-        $this->printEvent(
303
-            'testFinished',
304
-            [
305
-                'name'     => $test->getName(),
306
-                'duration' => (int) (\round($time, 2) * 1000)
307
-            ]
308
-        );
309
-    }
310
-
311
-    /**
312
-     * @param string $eventName
313
-     * @param array  $params
314
-     */
315
-    private function printEvent($eventName, $params = [])
316
-    {
317
-        $this->write("\n##teamcity[$eventName");
318
-
319
-        if ($this->flowId) {
320
-            $params['flowId'] = $this->flowId;
321
-        }
322
-
323
-        foreach ($params as $key => $value) {
324
-            $escapedValue = self::escapeValue($value);
325
-            $this->write(" $key='$escapedValue'");
326
-        }
327
-
328
-        $this->write("]\n");
329
-    }
330
-
331
-    /**
332
-     * @param \Exception $e
333
-     *
334
-     * @return string
335
-     */
336
-    private static function getMessage(\Exception $e)
337
-    {
338
-        $message = '';
339
-
340
-        if (!$e instanceof Exception) {
341
-            if (\strlen(\get_class($e)) != 0) {
342
-                $message .= \get_class($e);
343
-            }
344
-
345
-            if (\strlen($message) != 0 && \strlen($e->getMessage()) != 0) {
346
-                $message .= ' : ';
347
-            }
348
-        }
349
-
350
-        return $message . $e->getMessage();
351
-    }
352
-
353
-    /**
354
-     * @param \Exception $e
355
-     *
356
-     * @return string
357
-     */
358
-    private static function getDetails(\Exception $e)
359
-    {
360
-        $stackTrace = Filter::getFilteredStacktrace($e);
361
-        $previous   = $e instanceof ExceptionWrapper ?
362
-            $e->getPreviousWrapped() : $e->getPrevious();
363
-
364
-        while ($previous) {
365
-            $stackTrace .= "\nCaused by\n" .
366
-                TestFailure::exceptionToString($previous) . "\n" .
367
-                Filter::getFilteredStacktrace($previous);
368
-
369
-            $previous = $previous instanceof ExceptionWrapper ?
370
-                $previous->getPreviousWrapped() : $previous->getPrevious();
371
-        }
372
-
373
-        return ' ' . \str_replace("\n", "\n ", $stackTrace);
374
-    }
375
-
376
-    /**
377
-     * @param mixed $value
378
-     *
379
-     * @return string
380
-     */
381
-    private static function getPrimitiveValueAsString($value)
382
-    {
383
-        if (null === $value) {
384
-            return 'null';
385
-        }
386
-
387
-        if (\is_bool($value)) {
388
-            return $value == true ? 'true' : 'false';
389
-        }
390
-
391
-        if (\is_scalar($value)) {
392
-            return \print_r($value, true);
393
-        }
394
-    }
395
-
396
-    /**
397
-     * @param  $text
398
-     *
399
-     * @return string
400
-     */
401
-    private static function escapeValue($text)
402
-    {
403
-        $text = \str_replace('|', '||', $text);
404
-        $text = \str_replace("'", "|'", $text);
405
-        $text = \str_replace("\n", '|n', $text);
406
-        $text = \str_replace("\r", '|r', $text);
407
-        $text = \str_replace(']', '|]', $text);
408
-        $text = \str_replace('[', '|[', $text);
409
-
410
-        return $text;
411
-    }
412
-
413
-    /**
414
-     * @param string $className
415
-     *
416
-     * @return string
417
-     */
418
-    private static function getFileName($className)
419
-    {
420
-        $reflectionClass = new ReflectionClass($className);
421
-
422
-        return $reflectionClass->getFileName();
423
-    }
34
+	/**
35
+	 * @var bool
36
+	 */
37
+	private $isSummaryTestCountPrinted = false;
38
+
39
+	/**
40
+	 * @var string
41
+	 */
42
+	private $startedTestName;
43
+
44
+	/**
45
+	 * @var int|false
46
+	 */
47
+	private $flowId;
48
+
49
+	/**
50
+	 * @param string $progress
51
+	 */
52
+	protected function writeProgress($progress)
53
+	{
54
+	}
55
+
56
+	/**
57
+	 * @param TestResult $result
58
+	 */
59
+	public function printResult(TestResult $result)
60
+	{
61
+		$this->printHeader();
62
+		$this->printFooter($result);
63
+	}
64
+
65
+	/**
66
+	 * An error occurred.
67
+	 *
68
+	 * @param Test       $test
69
+	 * @param \Exception $e
70
+	 * @param float      $time
71
+	 */
72
+	public function addError(Test $test, \Exception $e, $time)
73
+	{
74
+		$this->printEvent(
75
+			'testFailed',
76
+			[
77
+				'name'    => $test->getName(),
78
+				'message' => self::getMessage($e),
79
+				'details' => self::getDetails($e),
80
+			]
81
+		);
82
+	}
83
+
84
+	/**
85
+	 * A warning occurred.
86
+	 *
87
+	 * @param Test    $test
88
+	 * @param Warning $e
89
+	 * @param float   $time
90
+	 */
91
+	public function addWarning(Test $test, Warning $e, $time)
92
+	{
93
+		$this->printEvent(
94
+			'testFailed',
95
+			[
96
+				'name'    => $test->getName(),
97
+				'message' => self::getMessage($e),
98
+				'details' => self::getDetails($e)
99
+			]
100
+		);
101
+	}
102
+
103
+	/**
104
+	 * A failure occurred.
105
+	 *
106
+	 * @param Test                 $test
107
+	 * @param AssertionFailedError $e
108
+	 * @param float                $time
109
+	 */
110
+	public function addFailure(Test $test, AssertionFailedError $e, $time)
111
+	{
112
+		$parameters = [
113
+			'name'    => $test->getName(),
114
+			'message' => self::getMessage($e),
115
+			'details' => self::getDetails($e),
116
+		];
117
+
118
+		if ($e instanceof ExpectationFailedException) {
119
+			$comparisonFailure = $e->getComparisonFailure();
120
+
121
+			if ($comparisonFailure instanceof ComparisonFailure) {
122
+				$expectedString = $comparisonFailure->getExpectedAsString();
123
+
124
+				if (null === $expectedString || empty($expectedString)) {
125
+					$expectedString = self::getPrimitiveValueAsString($comparisonFailure->getExpected());
126
+				}
127
+
128
+				$actualString = $comparisonFailure->getActualAsString();
129
+
130
+				if (null === $actualString || empty($actualString)) {
131
+					$actualString = self::getPrimitiveValueAsString($comparisonFailure->getActual());
132
+				}
133
+
134
+				if (null !== $actualString && null !== $expectedString) {
135
+					$parameters['type']     = 'comparisonFailure';
136
+					$parameters['actual']   = $actualString;
137
+					$parameters['expected'] = $expectedString;
138
+				}
139
+			}
140
+		}
141
+
142
+		$this->printEvent('testFailed', $parameters);
143
+	}
144
+
145
+	/**
146
+	 * Incomplete test.
147
+	 *
148
+	 * @param Test       $test
149
+	 * @param \Exception $e
150
+	 * @param float      $time
151
+	 */
152
+	public function addIncompleteTest(Test $test, \Exception $e, $time)
153
+	{
154
+		$this->printIgnoredTest($test->getName(), $e);
155
+	}
156
+
157
+	/**
158
+	 * Risky test.
159
+	 *
160
+	 * @param Test       $test
161
+	 * @param \Exception $e
162
+	 * @param float      $time
163
+	 */
164
+	public function addRiskyTest(Test $test, \Exception $e, $time)
165
+	{
166
+		$this->addError($test, $e, $time);
167
+	}
168
+
169
+	/**
170
+	 * Skipped test.
171
+	 *
172
+	 * @param Test       $test
173
+	 * @param \Exception $e
174
+	 * @param float      $time
175
+	 */
176
+	public function addSkippedTest(Test $test, \Exception $e, $time)
177
+	{
178
+		$testName = $test->getName();
179
+		if ($this->startedTestName != $testName) {
180
+			$this->startTest($test);
181
+			$this->printIgnoredTest($testName, $e);
182
+			$this->endTest($test, $time);
183
+		} else {
184
+			$this->printIgnoredTest($testName, $e);
185
+		}
186
+	}
187
+
188
+	public function printIgnoredTest($testName, \Exception $e)
189
+	{
190
+		$this->printEvent(
191
+			'testIgnored',
192
+			[
193
+				'name'    => $testName,
194
+				'message' => self::getMessage($e),
195
+				'details' => self::getDetails($e),
196
+			]
197
+		);
198
+	}
199
+
200
+	/**
201
+	 * A testsuite started.
202
+	 *
203
+	 * @param TestSuite $suite
204
+	 */
205
+	public function startTestSuite(TestSuite $suite)
206
+	{
207
+		if (\stripos(\ini_get('disable_functions'), 'getmypid') === false) {
208
+			$this->flowId = \getmypid();
209
+		} else {
210
+			$this->flowId = false;
211
+		}
212
+
213
+		if (!$this->isSummaryTestCountPrinted) {
214
+			$this->isSummaryTestCountPrinted = true;
215
+
216
+			$this->printEvent(
217
+				'testCount',
218
+				['count' => \count($suite)]
219
+			);
220
+		}
221
+
222
+		$suiteName = $suite->getName();
223
+
224
+		if (empty($suiteName)) {
225
+			return;
226
+		}
227
+
228
+		$parameters = ['name' => $suiteName];
229
+
230
+		if (\class_exists($suiteName, false)) {
231
+			$fileName                   = self::getFileName($suiteName);
232
+			$parameters['locationHint'] = "php_qn://$fileName::\\$suiteName";
233
+		} else {
234
+			$split = \preg_split('/::/', $suiteName);
235
+
236
+			if (\count($split) == 2 && \method_exists($split[0], $split[1])) {
237
+				$fileName                   = self::getFileName($split[0]);
238
+				$parameters['locationHint'] = "php_qn://$fileName::\\$suiteName";
239
+				$parameters['name']         = $split[1];
240
+			}
241
+		}
242
+
243
+		$this->printEvent('testSuiteStarted', $parameters);
244
+	}
245
+
246
+	/**
247
+	 * A testsuite ended.
248
+	 *
249
+	 * @param TestSuite $suite
250
+	 */
251
+	public function endTestSuite(TestSuite $suite)
252
+	{
253
+		$suiteName = $suite->getName();
254
+
255
+		if (empty($suiteName)) {
256
+			return;
257
+		}
258
+
259
+		$parameters = ['name' => $suiteName];
260
+
261
+		if (!\class_exists($suiteName, false)) {
262
+			$split = \preg_split('/::/', $suiteName);
263
+
264
+			if (\count($split) == 2 && \method_exists($split[0], $split[1])) {
265
+				$parameters['name'] = $split[1];
266
+			}
267
+		}
268
+
269
+		$this->printEvent('testSuiteFinished', $parameters);
270
+	}
271
+
272
+	/**
273
+	 * A test started.
274
+	 *
275
+	 * @param Test $test
276
+	 */
277
+	public function startTest(Test $test)
278
+	{
279
+		$testName              = $test->getName();
280
+		$this->startedTestName = $testName;
281
+		$params                = ['name' => $testName];
282
+
283
+		if ($test instanceof TestCase) {
284
+			$className              = \get_class($test);
285
+			$fileName               = self::getFileName($className);
286
+			$params['locationHint'] = "php_qn://$fileName::\\$className::$testName";
287
+		}
288
+
289
+		$this->printEvent('testStarted', $params);
290
+	}
291
+
292
+	/**
293
+	 * A test ended.
294
+	 *
295
+	 * @param Test  $test
296
+	 * @param float $time
297
+	 */
298
+	public function endTest(Test $test, $time)
299
+	{
300
+		parent::endTest($test, $time);
301
+
302
+		$this->printEvent(
303
+			'testFinished',
304
+			[
305
+				'name'     => $test->getName(),
306
+				'duration' => (int) (\round($time, 2) * 1000)
307
+			]
308
+		);
309
+	}
310
+
311
+	/**
312
+	 * @param string $eventName
313
+	 * @param array  $params
314
+	 */
315
+	private function printEvent($eventName, $params = [])
316
+	{
317
+		$this->write("\n##teamcity[$eventName");
318
+
319
+		if ($this->flowId) {
320
+			$params['flowId'] = $this->flowId;
321
+		}
322
+
323
+		foreach ($params as $key => $value) {
324
+			$escapedValue = self::escapeValue($value);
325
+			$this->write(" $key='$escapedValue'");
326
+		}
327
+
328
+		$this->write("]\n");
329
+	}
330
+
331
+	/**
332
+	 * @param \Exception $e
333
+	 *
334
+	 * @return string
335
+	 */
336
+	private static function getMessage(\Exception $e)
337
+	{
338
+		$message = '';
339
+
340
+		if (!$e instanceof Exception) {
341
+			if (\strlen(\get_class($e)) != 0) {
342
+				$message .= \get_class($e);
343
+			}
344
+
345
+			if (\strlen($message) != 0 && \strlen($e->getMessage()) != 0) {
346
+				$message .= ' : ';
347
+			}
348
+		}
349
+
350
+		return $message . $e->getMessage();
351
+	}
352
+
353
+	/**
354
+	 * @param \Exception $e
355
+	 *
356
+	 * @return string
357
+	 */
358
+	private static function getDetails(\Exception $e)
359
+	{
360
+		$stackTrace = Filter::getFilteredStacktrace($e);
361
+		$previous   = $e instanceof ExceptionWrapper ?
362
+			$e->getPreviousWrapped() : $e->getPrevious();
363
+
364
+		while ($previous) {
365
+			$stackTrace .= "\nCaused by\n" .
366
+				TestFailure::exceptionToString($previous) . "\n" .
367
+				Filter::getFilteredStacktrace($previous);
368
+
369
+			$previous = $previous instanceof ExceptionWrapper ?
370
+				$previous->getPreviousWrapped() : $previous->getPrevious();
371
+		}
372
+
373
+		return ' ' . \str_replace("\n", "\n ", $stackTrace);
374
+	}
375
+
376
+	/**
377
+	 * @param mixed $value
378
+	 *
379
+	 * @return string
380
+	 */
381
+	private static function getPrimitiveValueAsString($value)
382
+	{
383
+		if (null === $value) {
384
+			return 'null';
385
+		}
386
+
387
+		if (\is_bool($value)) {
388
+			return $value == true ? 'true' : 'false';
389
+		}
390
+
391
+		if (\is_scalar($value)) {
392
+			return \print_r($value, true);
393
+		}
394
+	}
395
+
396
+	/**
397
+	 * @param  $text
398
+	 *
399
+	 * @return string
400
+	 */
401
+	private static function escapeValue($text)
402
+	{
403
+		$text = \str_replace('|', '||', $text);
404
+		$text = \str_replace("'", "|'", $text);
405
+		$text = \str_replace("\n", '|n', $text);
406
+		$text = \str_replace("\r", '|r', $text);
407
+		$text = \str_replace(']', '|]', $text);
408
+		$text = \str_replace('[', '|[', $text);
409
+
410
+		return $text;
411
+	}
412
+
413
+	/**
414
+	 * @param string $className
415
+	 *
416
+	 * @return string
417
+	 */
418
+	private static function getFileName($className)
419
+	{
420
+		$reflectionClass = new ReflectionClass($className);
421
+
422
+		return $reflectionClass->getFileName();
423
+	}
424 424
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -14,40 +14,40 @@
 block discarded – undo
14 14
  */
15 15
 class TextResultPrinter extends ResultPrinter
16 16
 {
17
-    /**
18
-     * Handler for 'start class' event.
19
-     *
20
-     * @param string $name
21
-     */
22
-    protected function startClass($name)
23
-    {
24
-        $this->write($this->currentTestClassPrettified . "\n");
25
-    }
17
+	/**
18
+	 * Handler for 'start class' event.
19
+	 *
20
+	 * @param string $name
21
+	 */
22
+	protected function startClass($name)
23
+	{
24
+		$this->write($this->currentTestClassPrettified . "\n");
25
+	}
26 26
 
27
-    /**
28
-     * Handler for 'on test' event.
29
-     *
30
-     * @param string $name
31
-     * @param bool   $success
32
-     */
33
-    protected function onTest($name, $success = true)
34
-    {
35
-        if ($success) {
36
-            $this->write(' [x] ');
37
-        } else {
38
-            $this->write(' [ ] ');
39
-        }
27
+	/**
28
+	 * Handler for 'on test' event.
29
+	 *
30
+	 * @param string $name
31
+	 * @param bool   $success
32
+	 */
33
+	protected function onTest($name, $success = true)
34
+	{
35
+		if ($success) {
36
+			$this->write(' [x] ');
37
+		} else {
38
+			$this->write(' [ ] ');
39
+		}
40 40
 
41
-        $this->write($name . "\n");
42
-    }
41
+		$this->write($name . "\n");
42
+	}
43 43
 
44
-    /**
45
-     * Handler for 'end class' event.
46
-     *
47
-     * @param string $name
48
-     */
49
-    protected function endClass($name)
50
-    {
51
-        $this->write("\n");
52
-    }
44
+	/**
45
+	 * Handler for 'end class' event.
46
+	 *
47
+	 * @param string $name
48
+	 */
49
+	protected function endClass($name)
50
+	{
51
+		$this->write("\n");
52
+	}
53 53
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php 1 patch
Indentation   +212 added lines, -212 removed lines patch added patch discarded remove patch
@@ -23,216 +23,216 @@
 block discarded – undo
23 23
 
24 24
 class XmlResultPrinter extends Printer implements TestListener
25 25
 {
26
-    /**
27
-     * @var DOMDocument
28
-     */
29
-    private $document;
30
-
31
-    /**
32
-     * @var DOMElement
33
-     */
34
-    private $root;
35
-
36
-    /**
37
-     * @var NamePrettifier
38
-     */
39
-    private $prettifier;
40
-
41
-    /**
42
-     * @var \Exception|null
43
-     */
44
-    private $exception;
45
-
46
-    /**
47
-     * @param string|resource $out
48
-     */
49
-    public function __construct($out = null)
50
-    {
51
-        $this->document               = new DOMDocument('1.0', 'UTF-8');
52
-        $this->document->formatOutput = true;
53
-
54
-        $this->root = $this->document->createElement('tests');
55
-        $this->document->appendChild($this->root);
56
-
57
-        $this->prettifier = new NamePrettifier;
58
-
59
-        parent::__construct($out);
60
-    }
61
-
62
-    /**
63
-     * Flush buffer and close output.
64
-     */
65
-    public function flush()
66
-    {
67
-        $this->write($this->document->saveXML());
68
-
69
-        parent::flush();
70
-    }
71
-
72
-    /**
73
-     * An error occurred.
74
-     *
75
-     * @param Test       $test
76
-     * @param \Exception $e
77
-     * @param float      $time
78
-     */
79
-    public function addError(Test $test, \Exception $e, $time)
80
-    {
81
-        $this->exception = $e;
82
-    }
83
-
84
-    /**
85
-     * A warning occurred.
86
-     *
87
-     * @param Test    $test
88
-     * @param Warning $e
89
-     * @param float   $time
90
-     */
91
-    public function addWarning(Test $test, Warning $e, $time)
92
-    {
93
-    }
94
-
95
-    /**
96
-     * A failure occurred.
97
-     *
98
-     * @param Test                 $test
99
-     * @param AssertionFailedError $e
100
-     * @param float                $time
101
-     */
102
-    public function addFailure(Test $test, AssertionFailedError $e, $time)
103
-    {
104
-        $this->exception = $e;
105
-    }
106
-
107
-    /**
108
-     * Incomplete test.
109
-     *
110
-     * @param Test       $test
111
-     * @param \Exception $e
112
-     * @param float      $time
113
-     */
114
-    public function addIncompleteTest(Test $test, \Exception $e, $time)
115
-    {
116
-    }
117
-
118
-    /**
119
-     * Risky test.
120
-     *
121
-     * @param Test       $test
122
-     * @param \Exception $e
123
-     * @param float      $time
124
-     */
125
-    public function addRiskyTest(Test $test, \Exception $e, $time)
126
-    {
127
-    }
128
-
129
-    /**
130
-     * Skipped test.
131
-     *
132
-     * @param Test       $test
133
-     * @param \Exception $e
134
-     * @param float      $time
135
-     */
136
-    public function addSkippedTest(Test $test, \Exception $e, $time)
137
-    {
138
-    }
139
-
140
-    /**
141
-     * A test suite started.
142
-     *
143
-     * @param TestSuite $suite
144
-     */
145
-    public function startTestSuite(TestSuite $suite)
146
-    {
147
-    }
148
-
149
-    /**
150
-     * A test suite ended.
151
-     *
152
-     * @param TestSuite $suite
153
-     */
154
-    public function endTestSuite(TestSuite $suite)
155
-    {
156
-    }
157
-
158
-    /**
159
-     * A test started.
160
-     *
161
-     * @param Test $test
162
-     */
163
-    public function startTest(Test $test)
164
-    {
165
-        $this->exception = null;
166
-    }
167
-
168
-    /**
169
-     * A test ended.
170
-     *
171
-     * @param Test  $test
172
-     * @param float $time
173
-     */
174
-    public function endTest(Test $test, $time)
175
-    {
176
-        if (!$test instanceof TestCase) {
177
-            return;
178
-        }
179
-
180
-        /* @var TestCase $test */
181
-
182
-        $groups = \array_filter(
183
-            $test->getGroups(),
184
-            function ($group) {
185
-                if ($group == 'small' || $group == 'medium' || $group == 'large') {
186
-                    return false;
187
-                }
188
-
189
-                return true;
190
-            }
191
-        );
192
-
193
-        $node = $this->document->createElement('test');
194
-
195
-        $node->setAttribute('className', \get_class($test));
196
-        $node->setAttribute('methodName', $test->getName());
197
-        $node->setAttribute('prettifiedClassName', $this->prettifier->prettifyTestClass(\get_class($test)));
198
-        $node->setAttribute('prettifiedMethodName', $this->prettifier->prettifyTestMethod($test->getName()));
199
-        $node->setAttribute('status', $test->getStatus());
200
-        $node->setAttribute('time', $time);
201
-        $node->setAttribute('size', $test->getSize());
202
-        $node->setAttribute('groups', \implode(',', $groups));
203
-
204
-        $inlineAnnotations = \PHPUnit\Util\Test::getInlineAnnotations(\get_class($test), $test->getName());
205
-
206
-        if (isset($inlineAnnotations['given']) && isset($inlineAnnotations['when']) && isset($inlineAnnotations['then'])) {
207
-            $node->setAttribute('given', $inlineAnnotations['given']['value']);
208
-            $node->setAttribute('givenStartLine', $inlineAnnotations['given']['line']);
209
-            $node->setAttribute('when', $inlineAnnotations['when']['value']);
210
-            $node->setAttribute('whenStartLine', $inlineAnnotations['when']['line']);
211
-            $node->setAttribute('then', $inlineAnnotations['then']['value']);
212
-            $node->setAttribute('thenStartLine', $inlineAnnotations['then']['line']);
213
-        }
214
-
215
-        if ($this->exception !== null) {
216
-            if ($this->exception instanceof Exception) {
217
-                $steps = $this->exception->getSerializableTrace();
218
-            } else {
219
-                $steps = $this->exception->getTrace();
220
-            }
221
-
222
-            $class = new ReflectionClass($test);
223
-            $file  = $class->getFileName();
224
-
225
-            foreach ($steps as $step) {
226
-                if (isset($step['file']) && $step['file'] == $file) {
227
-                    $node->setAttribute('exceptionLine', $step['line']);
228
-
229
-                    break;
230
-                }
231
-            }
232
-
233
-            $node->setAttribute('exceptionMessage', $this->exception->getMessage());
234
-        }
235
-
236
-        $this->root->appendChild($node);
237
-    }
26
+	/**
27
+	 * @var DOMDocument
28
+	 */
29
+	private $document;
30
+
31
+	/**
32
+	 * @var DOMElement
33
+	 */
34
+	private $root;
35
+
36
+	/**
37
+	 * @var NamePrettifier
38
+	 */
39
+	private $prettifier;
40
+
41
+	/**
42
+	 * @var \Exception|null
43
+	 */
44
+	private $exception;
45
+
46
+	/**
47
+	 * @param string|resource $out
48
+	 */
49
+	public function __construct($out = null)
50
+	{
51
+		$this->document               = new DOMDocument('1.0', 'UTF-8');
52
+		$this->document->formatOutput = true;
53
+
54
+		$this->root = $this->document->createElement('tests');
55
+		$this->document->appendChild($this->root);
56
+
57
+		$this->prettifier = new NamePrettifier;
58
+
59
+		parent::__construct($out);
60
+	}
61
+
62
+	/**
63
+	 * Flush buffer and close output.
64
+	 */
65
+	public function flush()
66
+	{
67
+		$this->write($this->document->saveXML());
68
+
69
+		parent::flush();
70
+	}
71
+
72
+	/**
73
+	 * An error occurred.
74
+	 *
75
+	 * @param Test       $test
76
+	 * @param \Exception $e
77
+	 * @param float      $time
78
+	 */
79
+	public function addError(Test $test, \Exception $e, $time)
80
+	{
81
+		$this->exception = $e;
82
+	}
83
+
84
+	/**
85
+	 * A warning occurred.
86
+	 *
87
+	 * @param Test    $test
88
+	 * @param Warning $e
89
+	 * @param float   $time
90
+	 */
91
+	public function addWarning(Test $test, Warning $e, $time)
92
+	{
93
+	}
94
+
95
+	/**
96
+	 * A failure occurred.
97
+	 *
98
+	 * @param Test                 $test
99
+	 * @param AssertionFailedError $e
100
+	 * @param float                $time
101
+	 */
102
+	public function addFailure(Test $test, AssertionFailedError $e, $time)
103
+	{
104
+		$this->exception = $e;
105
+	}
106
+
107
+	/**
108
+	 * Incomplete test.
109
+	 *
110
+	 * @param Test       $test
111
+	 * @param \Exception $e
112
+	 * @param float      $time
113
+	 */
114
+	public function addIncompleteTest(Test $test, \Exception $e, $time)
115
+	{
116
+	}
117
+
118
+	/**
119
+	 * Risky test.
120
+	 *
121
+	 * @param Test       $test
122
+	 * @param \Exception $e
123
+	 * @param float      $time
124
+	 */
125
+	public function addRiskyTest(Test $test, \Exception $e, $time)
126
+	{
127
+	}
128
+
129
+	/**
130
+	 * Skipped test.
131
+	 *
132
+	 * @param Test       $test
133
+	 * @param \Exception $e
134
+	 * @param float      $time
135
+	 */
136
+	public function addSkippedTest(Test $test, \Exception $e, $time)
137
+	{
138
+	}
139
+
140
+	/**
141
+	 * A test suite started.
142
+	 *
143
+	 * @param TestSuite $suite
144
+	 */
145
+	public function startTestSuite(TestSuite $suite)
146
+	{
147
+	}
148
+
149
+	/**
150
+	 * A test suite ended.
151
+	 *
152
+	 * @param TestSuite $suite
153
+	 */
154
+	public function endTestSuite(TestSuite $suite)
155
+	{
156
+	}
157
+
158
+	/**
159
+	 * A test started.
160
+	 *
161
+	 * @param Test $test
162
+	 */
163
+	public function startTest(Test $test)
164
+	{
165
+		$this->exception = null;
166
+	}
167
+
168
+	/**
169
+	 * A test ended.
170
+	 *
171
+	 * @param Test  $test
172
+	 * @param float $time
173
+	 */
174
+	public function endTest(Test $test, $time)
175
+	{
176
+		if (!$test instanceof TestCase) {
177
+			return;
178
+		}
179
+
180
+		/* @var TestCase $test */
181
+
182
+		$groups = \array_filter(
183
+			$test->getGroups(),
184
+			function ($group) {
185
+				if ($group == 'small' || $group == 'medium' || $group == 'large') {
186
+					return false;
187
+				}
188
+
189
+				return true;
190
+			}
191
+		);
192
+
193
+		$node = $this->document->createElement('test');
194
+
195
+		$node->setAttribute('className', \get_class($test));
196
+		$node->setAttribute('methodName', $test->getName());
197
+		$node->setAttribute('prettifiedClassName', $this->prettifier->prettifyTestClass(\get_class($test)));
198
+		$node->setAttribute('prettifiedMethodName', $this->prettifier->prettifyTestMethod($test->getName()));
199
+		$node->setAttribute('status', $test->getStatus());
200
+		$node->setAttribute('time', $time);
201
+		$node->setAttribute('size', $test->getSize());
202
+		$node->setAttribute('groups', \implode(',', $groups));
203
+
204
+		$inlineAnnotations = \PHPUnit\Util\Test::getInlineAnnotations(\get_class($test), $test->getName());
205
+
206
+		if (isset($inlineAnnotations['given']) && isset($inlineAnnotations['when']) && isset($inlineAnnotations['then'])) {
207
+			$node->setAttribute('given', $inlineAnnotations['given']['value']);
208
+			$node->setAttribute('givenStartLine', $inlineAnnotations['given']['line']);
209
+			$node->setAttribute('when', $inlineAnnotations['when']['value']);
210
+			$node->setAttribute('whenStartLine', $inlineAnnotations['when']['line']);
211
+			$node->setAttribute('then', $inlineAnnotations['then']['value']);
212
+			$node->setAttribute('thenStartLine', $inlineAnnotations['then']['line']);
213
+		}
214
+
215
+		if ($this->exception !== null) {
216
+			if ($this->exception instanceof Exception) {
217
+				$steps = $this->exception->getSerializableTrace();
218
+			} else {
219
+				$steps = $this->exception->getTrace();
220
+			}
221
+
222
+			$class = new ReflectionClass($test);
223
+			$file  = $class->getFileName();
224
+
225
+			foreach ($steps as $step) {
226
+				if (isset($step['file']) && $step['file'] == $file) {
227
+					$node->setAttribute('exceptionLine', $step['line']);
228
+
229
+					break;
230
+				}
231
+			}
232
+
233
+			$node->setAttribute('exceptionMessage', $this->exception->getMessage());
234
+		}
235
+
236
+		$this->root->appendChild($node);
237
+	}
238 238
 }
Please login to merge, or discard this patch.
vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php 1 patch
Indentation   +124 added lines, -124 removed lines patch added patch discarded remove patch
@@ -15,128 +15,128 @@
 block discarded – undo
15 15
  */
16 16
 class NamePrettifier
17 17
 {
18
-    /**
19
-     * @var string
20
-     */
21
-    protected $prefix = 'Test';
22
-
23
-    /**
24
-     * @var string
25
-     */
26
-    protected $suffix = 'Test';
27
-
28
-    /**
29
-     * @var array
30
-     */
31
-    protected $strings = [];
32
-
33
-    /**
34
-     * Prettifies the name of a test class.
35
-     *
36
-     * @param string $name
37
-     *
38
-     * @return string
39
-     */
40
-    public function prettifyTestClass($name)
41
-    {
42
-        $title = $name;
43
-
44
-        if ($this->suffix !== null &&
45
-            $this->suffix == \substr($name, -1 * \strlen($this->suffix))) {
46
-            $title = \substr($title, 0, \strripos($title, $this->suffix));
47
-        }
48
-
49
-        if ($this->prefix !== null &&
50
-            $this->prefix == \substr($name, 0, \strlen($this->prefix))) {
51
-            $title = \substr($title, \strlen($this->prefix));
52
-        }
53
-
54
-        if (\substr($title, 0, 1) == '\\') {
55
-            $title = \substr($title, 1);
56
-        }
57
-
58
-        return $title;
59
-    }
60
-
61
-    /**
62
-     * Prettifies the name of a test method.
63
-     *
64
-     * @param string $name
65
-     *
66
-     * @return string
67
-     */
68
-    public function prettifyTestMethod($name)
69
-    {
70
-        $buffer = '';
71
-
72
-        if (!\is_string($name) || \strlen($name) == 0) {
73
-            return $buffer;
74
-        }
75
-
76
-        $string = \preg_replace('#\d+$#', '', $name, -1, $count);
77
-
78
-        if (\in_array($string, $this->strings)) {
79
-            $name = $string;
80
-        } elseif ($count == 0) {
81
-            $this->strings[] = $string;
82
-        }
83
-
84
-        if (\substr($name, 0, 4) == 'test') {
85
-            $name = \substr($name, 4);
86
-        }
87
-
88
-        if (\strlen($name) == 0) {
89
-            return $buffer;
90
-        }
91
-
92
-        $name[0] = \strtoupper($name[0]);
93
-
94
-        if (\strpos($name, '_') !== false) {
95
-            return \trim(\str_replace('_', ' ', $name));
96
-        }
97
-
98
-        $max        = \strlen($name);
99
-        $wasNumeric = false;
100
-
101
-        for ($i = 0; $i < $max; $i++) {
102
-            if ($i > 0 && \ord($name[$i]) >= 65 && \ord($name[$i]) <= 90) {
103
-                $buffer .= ' ' . \strtolower($name[$i]);
104
-            } else {
105
-                $isNumeric = \is_numeric($name[$i]);
106
-
107
-                if (!$wasNumeric && $isNumeric) {
108
-                    $buffer .= ' ';
109
-                    $wasNumeric = true;
110
-                }
111
-
112
-                if ($wasNumeric && !$isNumeric) {
113
-                    $wasNumeric = false;
114
-                }
115
-
116
-                $buffer .= $name[$i];
117
-            }
118
-        }
119
-
120
-        return $buffer;
121
-    }
122
-
123
-    /**
124
-     * Sets the prefix of test names.
125
-     *
126
-     * @param string $prefix
127
-     */
128
-    public function setPrefix($prefix)
129
-    {
130
-        $this->prefix = $prefix;
131
-    }
132
-
133
-    /**
134
-     * Sets the suffix of test names.
135
-     *
136
-     * @param string $suffix
137
-     */
138
-    public function setSuffix($suffix)
139
-    {
140
-        $this->suffix = $suffix;
141
-    }
18
+	/**
19
+	 * @var string
20
+	 */
21
+	protected $prefix = 'Test';
22
+
23
+	/**
24
+	 * @var string
25
+	 */
26
+	protected $suffix = 'Test';
27
+
28
+	/**
29
+	 * @var array
30
+	 */
31
+	protected $strings = [];
32
+
33
+	/**
34
+	 * Prettifies the name of a test class.
35
+	 *
36
+	 * @param string $name
37
+	 *
38
+	 * @return string
39
+	 */
40
+	public function prettifyTestClass($name)
41
+	{
42
+		$title = $name;
43
+
44
+		if ($this->suffix !== null &&
45
+			$this->suffix == \substr($name, -1 * \strlen($this->suffix))) {
46
+			$title = \substr($title, 0, \strripos($title, $this->suffix));
47
+		}
48
+
49
+		if ($this->prefix !== null &&
50
+			$this->prefix == \substr($name, 0, \strlen($this->prefix))) {
51
+			$title = \substr($title, \strlen($this->prefix));
52
+		}
53
+
54
+		if (\substr($title, 0, 1) == '\\') {
55
+			$title = \substr($title, 1);
56
+		}
57
+
58
+		return $title;
59
+	}
60
+
61
+	/**
62
+	 * Prettifies the name of a test method.
63
+	 *
64
+	 * @param string $name
65
+	 *
66
+	 * @return string
67
+	 */
68
+	public function prettifyTestMethod($name)
69
+	{
70
+		$buffer = '';
71
+
72
+		if (!\is_string($name) || \strlen($name) == 0) {
73
+			return $buffer;
74
+		}
75
+
76
+		$string = \preg_replace('#\d+$#', '', $name, -1, $count);
77
+
78
+		if (\in_array($string, $this->strings)) {
79
+			$name = $string;
80
+		} elseif ($count == 0) {
81
+			$this->strings[] = $string;
82
+		}
83
+
84
+		if (\substr($name, 0, 4) == 'test') {
85
+			$name = \substr($name, 4);
86
+		}
87
+
88
+		if (\strlen($name) == 0) {
89
+			return $buffer;
90
+		}
91
+
92
+		$name[0] = \strtoupper($name[0]);
93
+
94
+		if (\strpos($name, '_') !== false) {
95
+			return \trim(\str_replace('_', ' ', $name));
96
+		}
97
+
98
+		$max        = \strlen($name);
99
+		$wasNumeric = false;
100
+
101
+		for ($i = 0; $i < $max; $i++) {
102
+			if ($i > 0 && \ord($name[$i]) >= 65 && \ord($name[$i]) <= 90) {
103
+				$buffer .= ' ' . \strtolower($name[$i]);
104
+			} else {
105
+				$isNumeric = \is_numeric($name[$i]);
106
+
107
+				if (!$wasNumeric && $isNumeric) {
108
+					$buffer .= ' ';
109
+					$wasNumeric = true;
110
+				}
111
+
112
+				if ($wasNumeric && !$isNumeric) {
113
+					$wasNumeric = false;
114
+				}
115
+
116
+				$buffer .= $name[$i];
117
+			}
118
+		}
119
+
120
+		return $buffer;
121
+	}
122
+
123
+	/**
124
+	 * Sets the prefix of test names.
125
+	 *
126
+	 * @param string $prefix
127
+	 */
128
+	public function setPrefix($prefix)
129
+	{
130
+		$this->prefix = $prefix;
131
+	}
132
+
133
+	/**
134
+	 * Sets the suffix of test names.
135
+	 *
136
+	 * @param string $suffix
137
+	 */
138
+	public function setSuffix($suffix)
139
+	{
140
+		$this->suffix = $suffix;
141
+	}
142 142
 }
Please login to merge, or discard this patch.