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

Tester   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Test Coverage

Coverage 77.53%

Importance

Changes 37
Bugs 6 Features 8
Metric Value
wmc 25
eloc 87
c 37
b 6
f 8
dl 0
loc 159
ccs 69
cts 89
cp 0.7753
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setup() 0 3 1
B saveResults() 0 24 7
A printFailed() 0 8 2
A printResults() 0 25 4
A printSkipped() 0 8 3
A execute() 0 13 3
A getSuites() 0 6 2
A printInfo() 0 6 1
A __construct() 0 15 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
        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