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