Completed
Push — code-coverage ( 92d39b...48bbe4 )
by Jakub
02:13
created

TestCase::getJobs()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 28
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
cc 4
eloc 22
c 7
b 0
f 0
nc 3
nop 0
dl 0
loc 28
rs 9.568
1
<?php
2
declare(strict_types=1);
3
4
namespace MyTester;
5
6
use MyTester\Annotations\NetteReflectionEngine;
7
use MyTester\Annotations\Reader;
8
use ReflectionClass;
9
10
/**
11
 * One test suit
12
 *
13
 * @author Jakub Konečný
14
 */
15
abstract class TestCase {
16
  use \Nette\SmartObject;
17
  use TAssertions;
18
19
  public const RESULT_PASSED = ".";
20
  public const RESULT_SKIPPED = "s";
21
  public const RESULT_FAILED = "F";
22
  
23
  public const METHOD_PATTERN = '#^test[A-Z0-9_]#';
24
25
  protected SkipChecker $skipChecker;
26
  protected ShouldFailChecker $shouldFailChecker;
27
  protected DataProvider $dataProvider;
28
  protected Reader $annotationsReader;
29
30
  public function __construct() {
31
    $this->annotationsReader = new Reader();
32
    $this->annotationsReader->registerEngine(new NetteReflectionEngine());
33
    $this->skipChecker = new SkipChecker($this->annotationsReader);
34
    $this->shouldFailChecker = new ShouldFailChecker($this->annotationsReader);
35
    $this->dataProvider = new DataProvider($this->annotationsReader);
36
  }
37
  
38
  /**
39
   * Get list of jobs with parameters for current test suit
40
   * 
41
   * @return Job[]
42
   */
43
  protected function getJobs(): array {
44
    $jobs = [];
45
    $r = new ReflectionClass(static::class);
46
    $methods = array_values(preg_grep(static::METHOD_PATTERN, array_map(function(\ReflectionMethod $rm) {
47
      return $rm->getName();
48
    }, $r->getMethods())));
49
    foreach($methods as $method) {
50
      /** @var callable $callback */
51
      $callback = [$this, $method];
52
      $job = [
53
        "name" => $this->getJobName(static::class, $method),
54
        "callback" => $callback,
55
        "params" => [],
56
        "skip" => $this->skipChecker->shouldSkip(static::class, $method),
57
        "shouldFail" => $this->shouldFailChecker->shouldFail(static::class, $method),
58
      ];
59
      $data = $this->dataProvider->getData(static::class, $method);
60
      if(count($data) > 0) {
61
        foreach($data as $value) {
62
          $job["params"][0] = $value;
63
          $jobs[] = new Job($job["name"], $job["callback"], $job["params"], $job["skip"], $job["shouldFail"]);
64
          $job["params"] = [];
65
        }
66
      } else {
67
        $jobs[] = new Job($job["name"], $job["callback"], $job["params"], $job["skip"], $job["shouldFail"]);
68
      }
69
    }
70
    return $jobs;
71
  }
72
  
73
  /**
74
   * Get name of current test suit
75
   */
76
  protected function getSuitName(): string {
77
    $annotation = $this->annotationsReader->getAnnotation("testSuit", static::class);
78
    if($annotation !== null) {
79
      return $annotation;
80
    }
81
    return static::class;
82
  }
83
  
84
  /**
85
   * Get name for a job
86
   * @param string|object $class
87
   */
88
  protected function getJobName($class, string $method): string {
89
    $annotation = $this->annotationsReader->getAnnotation("test", $class, $method);
90
    if($annotation !== null) {
91
      return $annotation;
92
    }
93
    return $this->getSuitName() . "::" . $method;
94
  }
95
  
96
  /**
97
   * Called at start of the suit
98
   */
99
  public function startUp(): void {
100
  }
101
  
102
  /**
103
   * Called at end of the suit
104
   */
105
  public function shutDown(): void {
106
  }
107
  
108
  /**
109
   * Called before each job
110
   */
111
  public function setUp(): void {
112
  }
113
  
114
  /**
115
   * Called after each job
116
   */
117
  public function tearDown(): void {
118
  }
119
  
120
  protected function runJob(Job $job): string {
121
    /** @var array $callback */
122
    $callback = $job->callback;
123
    $jobName = $this->getJobName($callback[0], $callback[1]);
124
    Environment::$currentJob = $jobName;
125
    if(!$job->skip) {
126
      $this->setUp();
127
    }
128
    $job->execute();
129
    if(!$job->skip) {
130
      $this->tearDown();
131
    }
132
    Environment::$currentJob = "";
133
    switch($job->result) {
134
      case Job::RESULT_PASSED:
135
        return static::RESULT_PASSED;
136
      case Job::RESULT_SKIPPED:
137
        return static::RESULT_SKIPPED;
138
      case Job::RESULT_FAILED:
139
        return static::RESULT_FAILED;
140
    }
141
    return "";
142
  }
143
  
144
  /**
145
   * Runs the test suit
146
   */
147
  public function run(): bool {
148
    $this->startUp();
149
    $jobs = $this->getJobs();
150
    $passed = true;
151
    foreach($jobs as $job) {
152
      $result = $this->runJob($job);
153
      Environment::addResult($result);
154
      if($job->result === Job::RESULT_FAILED) {
155
        $passed = false;
156
      }
157
    }
158
    $this->shutDown();
159
    return $passed;
160
  }
161
}
162
?>