Completed
Push — master ( d7b1eb...111167 )
by Jakub
02:25
created

Tester.php$0 ➔ getSuites()   A

Complexity

Conditions 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 10
ccs 4
cts 4
cp 1
cc 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MyTester;
6
7
use Ayesh\PHP_Timer\Timer;
8
use Jean85\PrettyVersions;
9
use MyTester\Bridges\NetteRobotLoader\TestSuitesFinder;
10
use Nette\Utils\Finder;
11
12
/**
13
 * Automated tests runner
14
 *
15
 * @author Jakub Konečný
16
 * @property-read string[] $suites
17
 * @method void onExecute()
18
 */
19
final class Tester
20
{
21
    use \Nette\SmartObject;
22
23
    private const PACKAGE_NAME = "konecnyjakub/mytester";
24
    private const TIMER_NAME = "My Tester";
25
26
    /** @var string[] */
27
    private array $suites = [];
28
    /** @var callable[] */
29
    public array $onExecute = [];
30
    public ITestSuiteFactory $testSuiteFactory;
31
    public ITestsSuitesFinder $testsSuitesFinder;
32
    private string $folder;
33
    /** @var SkippedTest[] */
34
    private array $skipped = [];
35
    private string $results = "";
36
37 1
    public function __construct(
38
        string $folder,
39
        ITestsSuitesFinder $testsSuitesFinder = null,
40
        ITestSuiteFactory $testSuiteFactory = null
41
    ) {
42 1
        $this->onExecute[] = [$this, "setup"];
43 1
        $this->onExecute[] = [$this, "printInfo"];
44 1
        $this->testsSuitesFinder = $testsSuitesFinder ?? new TestSuitesFinder();
45 1
        $this->testSuiteFactory = $testSuiteFactory ?? new TestSuiteFactory();
46 1
        $this->folder = $folder;
47 1
    }
48
49
    /**
50
     * @return string[]
51
     */
52 1
    protected function getSuites(): array
53
    {
54 1
        if (count($this->suites) === 0) {
55 1
            $this->suites = $this->testsSuitesFinder->getSuites($this->folder);
56
        }
57 1
        return $this->suites;
58
    }
59
60
    /**
61
     * Execute all tests
62
     */
63 1
    public function execute(): void
64
    {
65 1
        $this->onExecute();
66 1
        $failed = false;
67 1
        foreach ($this->getSuites() as $suite) {
68 1
            $suite = $this->testSuiteFactory->create($suite);
69 1
            if (!$suite->run()) {
70
                $failed = true;
71
            }
72 1
            $this->saveResults($suite);
73
        }
74 1
        $this->printResults();
75 1
        exit((int) $failed);
76
    }
77
78 1
    private function setup(): void
79
    {
80 1
        Timer::start(static::TIMER_NAME);
81 1
    }
82
83
    /**
84
     * Print version of My Tester and PHP
85
     */
86 1
    private function printInfo(): void
87
    {
88 1
        echo "My Tester " . PrettyVersions::getVersion(static::PACKAGE_NAME) . "\n";
89 1
        echo "\n";
90 1
        echo "PHP " . PHP_VERSION . "(" . PHP_SAPI . ")\n";
91 1
        echo "\n";
92 1
    }
93
94 1
    private function printResults(): void
95
    {
96 1
        $results = $this->results;
97 1
        echo $results . "\n";
98 1
        $this->printSkipped();
99 1
        $failed = str_contains($results, TestCase::RESULT_FAILED);
100 1
        if (!$failed) {
101 1
            echo "\n";
102 1
            echo "OK";
103
        } else {
104
            $this->printFailed();
105
            echo "\n";
106
            echo "Failed";
107
        }
108 1
        $resultsLine = " (" . strlen($results) . " tests";
109 1
        if ($failed) {
110
            $resultsLine .= ", " . substr_count($results, TestCase::RESULT_FAILED) . " failed";
111
        }
112 1
        if (str_contains($results, TestCase::RESULT_SKIPPED)) {
113 1
            $resultsLine .= ", " . substr_count($results, TestCase::RESULT_SKIPPED) . " skipped";
114
        }
115 1
        Timer::stop(static::TIMER_NAME);
116 1
        $time = Timer::read(static::TIMER_NAME, Timer::FORMAT_HUMAN);
117 1
        $resultsLine .= ", $time)";
118 1
        echo $resultsLine . "\n";
119 1
    }
120
121
    /**
122
     * Print info about skipped tests
123
     */
124 1
    private function printSkipped(): void
125
    {
126 1
        foreach ($this->skipped as $skipped) {
127 1
            $reason = "";
128 1
            if ($skipped->reason) {
129 1
                $reason = ": {$skipped->reason}";
130
            }
131 1
            echo "Skipped $skipped->name$reason\n";
132
        }
133 1
    }
134
135
    /**
136
     * Print info about failed tests
137
     */
138
    private function printFailed(): void
139
    {
140
        $filenameSuffix = ".errors";
141
        $files = Finder::findFiles("*$filenameSuffix")->in($this->folder);
142
        /** @var \SplFileInfo $file */
143
        foreach ($files as $name => $file) {
144
            echo "--- " . $file->getBasename($filenameSuffix) . "\n";
145
            echo file_get_contents($name);
146
        }
147
    }
148
149 1
    private function saveResults(TestCase $testCase): void
150
    {
151 1
        $jobs = $testCase->jobs;
152 1
        foreach ($jobs as $job) {
153 1
            switch ($job->result) {
154 1
                case Job::RESULT_PASSED:
155 1
                    $result = TestCase::RESULT_PASSED;
156 1
                    break;
157 1
                case Job::RESULT_SKIPPED:
158 1
                    $result = TestCase::RESULT_SKIPPED;
159 1
                    $this->skipped[] = new SkippedTest($job->name, (is_string($job->skip) ? $job->skip : ""));
160 1
                    break;
161
                case Job::RESULT_FAILED:
162
                    $result = TestCase::RESULT_FAILED;
163
                    $output = $job->output;
164
                    if (strlen($output) > 0) {
165
                        file_put_contents("$this->folder/$job->name.errors", $output);
166
                    }
167
                    break;
168
                default:
169
                    $result = "";
170
                    break;
171
            }
172 1
            $this->results .= $result;
173
        }
174 1
    }
175
}
176