Test Failed
Push — master ( b8642a...c8c0c1 )
by Jakub
01:33
created

TestCase::getSuiteName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

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