Completed
Push — master ( d069a6...fdd0b3 )
by Jakub
01:41
created

Tester::printSkipped()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 10
cc 3
nc 3
nop 0
crap 3
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
        if ($testsSuitesFinder === null) {
45 1
            $testsSuitesFinder = new ChainTestsSuitesFinder();
46 1
            $testsSuitesFinder->registerFinder(new ComposerTestsSuitesFinder());
47 1
            $testsSuitesFinder->registerFinder(new TestSuitesFinder());
48
        }
49 1
        $this->testsSuitesFinder = $testsSuitesFinder;
50 1
        $this->testSuiteFactory = $testSuiteFactory ?? new TestSuiteFactory();
51 1
        $this->folder = $folder;
52 1
    }
53
54
    /**
55
     * @return string[]
56
     */
57 1
    protected function getSuites(): array
58
    {
59 1
        if (count($this->suites) === 0) {
60 1
            $this->suites = $this->testsSuitesFinder->getSuites($this->folder);
61
        }
62 1
        return $this->suites;
63
    }
64
65
    /**
66
     * Execute all tests
67
     */
68 1
    public function execute(): void
69
    {
70 1
        $this->onExecute();
71 1
        $failed = false;
72 1
        foreach ($this->getSuites() as $suite) {
73 1
            $suite = $this->testSuiteFactory->create($suite);
74 1
            if (!$suite->run()) {
75
                $failed = true;
76
            }
77 1
            $this->saveResults($suite);
78
        }
79 1
        $this->printResults();
80 1
        exit((int) $failed);
81
    }
82
83 1
    private function setup(): void
84
    {
85 1
        Timer::start(static::TIMER_NAME);
86 1
    }
87
88
    /**
89
     * Print version of My Tester and PHP
90
     */
91 1
    private function printInfo(): void
92
    {
93 1
        echo "My Tester " . PrettyVersions::getVersion(static::PACKAGE_NAME) . "\n";
94 1
        echo "\n";
95 1
        echo "PHP " . PHP_VERSION . "(" . PHP_SAPI . ")\n";
96 1
        echo "\n";
97 1
    }
98
99 1
    private function printResults(): void
100
    {
101 1
        $results = $this->results;
102 1
        echo $results . "\n";
103 1
        $this->printSkipped();
104 1
        $failed = str_contains($results, TestCase::RESULT_FAILED);
105 1
        if (!$failed) {
106 1
            echo "\n";
107 1
            echo "OK";
108
        } else {
109
            $this->printFailed();
110
            echo "\n";
111
            echo "Failed";
112
        }
113 1
        $resultsLine = " (" . strlen($results) . " tests";
114 1
        if ($failed) {
115
            $resultsLine .= ", " . substr_count($results, TestCase::RESULT_FAILED) . " failed";
116
        }
117 1
        if (str_contains($results, TestCase::RESULT_SKIPPED)) {
118 1
            $resultsLine .= ", " . substr_count($results, TestCase::RESULT_SKIPPED) . " skipped";
119
        }
120 1
        Timer::stop(static::TIMER_NAME);
121 1
        $time = Timer::read(static::TIMER_NAME, Timer::FORMAT_HUMAN);
122 1
        $resultsLine .= ", $time)";
123 1
        echo $resultsLine . "\n";
124 1
    }
125
126
    /**
127
     * Print info about skipped tests
128
     */
129 1
    private function printSkipped(): void
130
    {
131 1
        foreach ($this->skipped as $skipped) {
132 1
            $reason = "";
133 1
            if ($skipped->reason) {
134 1
                $reason = ": {$skipped->reason}";
135
            }
136 1
            echo "Skipped $skipped->name$reason\n";
137
        }
138 1
    }
139
140
    /**
141
     * Print info about failed tests
142
     */
143
    private function printFailed(): void
144
    {
145
        $filenameSuffix = ".errors";
146
        $files = Finder::findFiles("*$filenameSuffix")->in($this->folder);
147
        /** @var \SplFileInfo $file */
148
        foreach ($files as $name => $file) {
149
            echo "--- " . $file->getBasename($filenameSuffix) . "\n";
150
            echo file_get_contents($name);
151
        }
152
    }
153
154 1
    private function saveResults(TestCase $testCase): void
155
    {
156 1
        $jobs = $testCase->jobs;
157 1
        foreach ($jobs as $job) {
158 1
            switch ($job->result) {
159 1
                case Job::RESULT_PASSED:
160 1
                    $result = TestCase::RESULT_PASSED;
161 1
                    break;
162 1
                case Job::RESULT_SKIPPED:
163 1
                    $result = TestCase::RESULT_SKIPPED;
164 1
                    $this->skipped[] = new SkippedTest($job->name, (is_string($job->skip) ? $job->skip : ""));
165 1
                    break;
166
                case Job::RESULT_FAILED:
167
                    $result = TestCase::RESULT_FAILED;
168
                    $output = $job->output;
169
                    if (strlen($output) > 0) {
170
                        file_put_contents("$this->folder/$job->name.errors", $output);
171
                    }
172
                    break;
173
                default:
174
                    $result = "";
175
                    break;
176
            }
177 1
            $this->results .= $result;
178
        }
179 1
    }
180
}
181