Chris@13
|
1 <?php declare(strict_types=1);
|
Chris@13
|
2
|
Chris@13
|
3 namespace PhpParser;
|
Chris@13
|
4
|
Chris@13
|
5 class CodeTestParser
|
Chris@13
|
6 {
|
Chris@13
|
7 public function parseTest($code, $chunksPerTest) {
|
Chris@13
|
8 $code = canonicalize($code);
|
Chris@13
|
9
|
Chris@13
|
10 // evaluate @@{expr}@@ expressions
|
Chris@13
|
11 $code = preg_replace_callback(
|
Chris@13
|
12 '/@@\{(.*?)\}@@/',
|
Chris@13
|
13 function($matches) {
|
Chris@13
|
14 return eval('return ' . $matches[1] . ';');
|
Chris@13
|
15 },
|
Chris@13
|
16 $code
|
Chris@13
|
17 );
|
Chris@13
|
18
|
Chris@13
|
19 // parse sections
|
Chris@13
|
20 $parts = preg_split("/\n-----(?:\n|$)/", $code);
|
Chris@13
|
21
|
Chris@13
|
22 // first part is the name
|
Chris@13
|
23 $name = array_shift($parts);
|
Chris@13
|
24
|
Chris@13
|
25 // multiple sections possible with always two forming a pair
|
Chris@13
|
26 $chunks = array_chunk($parts, $chunksPerTest);
|
Chris@13
|
27 $tests = [];
|
Chris@13
|
28 foreach ($chunks as $i => $chunk) {
|
Chris@13
|
29 $lastPart = array_pop($chunk);
|
Chris@13
|
30 list($lastPart, $mode) = $this->extractMode($lastPart);
|
Chris@13
|
31 $tests[] = [$mode, array_merge($chunk, [$lastPart])];
|
Chris@13
|
32 }
|
Chris@13
|
33
|
Chris@13
|
34 return [$name, $tests];
|
Chris@13
|
35 }
|
Chris@13
|
36
|
Chris@13
|
37 public function reconstructTest($name, array $tests) {
|
Chris@13
|
38 $result = $name;
|
Chris@13
|
39 foreach ($tests as list($mode, $parts)) {
|
Chris@13
|
40 $lastPart = array_pop($parts);
|
Chris@13
|
41 foreach ($parts as $part) {
|
Chris@13
|
42 $result .= "\n-----\n$part";
|
Chris@13
|
43 }
|
Chris@13
|
44
|
Chris@13
|
45 $result .= "\n-----\n";
|
Chris@13
|
46 if (null !== $mode) {
|
Chris@13
|
47 $result .= "!!$mode\n";
|
Chris@13
|
48 }
|
Chris@13
|
49 $result .= $lastPart;
|
Chris@13
|
50 }
|
Chris@13
|
51 return $result;
|
Chris@13
|
52 }
|
Chris@13
|
53
|
Chris@13
|
54 private function extractMode($expected) {
|
Chris@13
|
55 $firstNewLine = strpos($expected, "\n");
|
Chris@13
|
56 if (false === $firstNewLine) {
|
Chris@13
|
57 $firstNewLine = strlen($expected);
|
Chris@13
|
58 }
|
Chris@13
|
59
|
Chris@13
|
60 $firstLine = substr($expected, 0, $firstNewLine);
|
Chris@13
|
61 if (0 !== strpos($firstLine, '!!')) {
|
Chris@13
|
62 return [$expected, null];
|
Chris@13
|
63 }
|
Chris@13
|
64
|
Chris@13
|
65 $expected = (string) substr($expected, $firstNewLine + 1);
|
Chris@13
|
66 return [$expected, substr($firstLine, 2)];
|
Chris@13
|
67 }
|
Chris@13
|
68 }
|