Completed
Push — master ( b25a31...347863 )
by Jakub
01:41
created

TestCase::startUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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