Completed
Push — master ( bc04e9...582cdb )
by Jakub
02:02
created

Tester.php$0 ➔ setup()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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