e7d7afb621ef9958e7043184e07caf4d164bdd24
[m6w6/seekat] / tests / bootstrap.php
1 <?php
2
3 require_once __DIR__."/../vendor/autoload.php";
4
5 function headers() : array {
6 static $headers;
7
8 if (!isset($headers)) {
9 if (($token = getenv("GITHUB_TOKEN"))) {
10 $headers["Authorization"] = "token $token";
11 } elseif (function_exists("posix_isatty") && defined("STDIN") && posix_isatty(STDIN)) {
12 fprintf(STDOUT, "GITHUB_TOKEN is not set in the environment, enter Y to continue without: ");
13 fflush(STDOUT);
14 if (strncasecmp(fgets(STDIN), "Y", 1)) {
15 exit;
16 }
17 $headers = [];
18 } else {
19 throw new Exception("GITHUB_TOKEN is not set in the environment");
20 }
21 }
22
23 return $headers;
24 }
25
26 function logger() : \Monolog\Logger {
27 static $logger;
28
29 if (!isset($logger)) {
30 $logger = new \Monolog\Logger(
31 "test",
32 [
33 new \Monolog\Handler\FingersCrossedHandler(
34 new \Monolog\Handler\StreamHandler(STDERR),
35 \Monolog\Logger::EMERGENCY
36 )
37 ]
38 );
39 }
40
41 return $logger;
42 }
43
44 class BaseTest extends \PHPUnit\Framework\TestCase
45 {
46 function provideAPI() {
47 $auth = \seekat\API\auth("token", getenv("GITHUB_TOKEN"));
48 $headers = headers();
49 $url = null;
50 $client = null;
51 $logger = logger();
52
53 return [
54 "using ReactPHP" => [new \seekat\API(\seekat\API\Future\react(), $headers, $url, $client, $logger)],
55 "using AmPHP" => [new \seekat\API(\seekat\API\Future\amp(), $headers, $url, $client, $logger)],
56 ];
57 }
58 }
59
60 trait ConsumePromise
61 {
62 function consumePromise($p, &$errors, &$results) {
63 if (method_exists($p, "done")) {
64 $p->then(function($result) use(&$results) {
65 if (isset($result)) {
66 $results[] = $result;
67 }
68 }, function($error) use (&$errors) {
69 if (isset($error)) {
70 $errors[] = $error;
71 }
72 });
73 } else {
74 $p->onResolve(function($error, $result) use(&$errors, &$results) {
75 if (isset($error)) {
76 $errors[] = $error;
77 }
78 if (isset($result)) {
79 $results[] = $result;
80 }
81 });
82 }
83 }
84 }
85
86 trait AssertSuccess
87 {
88 function assertAllSuccess(array $apis, ...$args) {
89 foreach ($apis as $api) {
90 $this->consumePromise($api->get(...$args), $errors, $results);
91 }
92 $api->send();
93 $this->assertEmpty($errors, "errors");
94 $this->assertNotEmpty($results, "results");
95 return $results;
96 }
97
98 function assertSuccess(seekat\API $api, ...$args) {
99 $this->consumePromise($api->get(...$args), $errors, $results);
100 $api->send();
101 $this->assertEmpty($errors, "errors");
102 $this->assertNotEmpty($results, "results");
103 return $results[0];
104 }
105 }
106
107 trait AssertCancelled
108 {
109 function assertCancelled($promise) {
110 $this->consumePromise($promise, $errors, $results);
111
112 $this->assertEmpty($results);
113 $this->assertStringMatchesFormat("%SCancelled%S", \seekat\Exception\message($errors[0]));
114 }
115 }
116
117 trait AssertFailure
118 {
119 function assertFailure(seekat\API $api, ...$args) {
120 $this->consumePromise($api->get(...$args), $errors, $results);
121 $api->send();
122 $this->assertNotEmpty($errors, "errors");
123 $this->assertEmpty($results, "results");
124 return $errors[0];
125 }
126 }
127
128 class CombinedTestdoxPrinter extends PHPUnit\TextUI\DefaultResultPrinter
129 {
130 function isTestClass(PHPUnit\Framework\TestSuite $suite) {
131 $suiteName = $suite->getName();
132 return false === strpos($suiteName, "::")
133 && substr($suiteName, -4) === "Test";
134 }
135
136 function startTestSuite(PHPUnit\Framework\TestSuite $suite) : void {
137 if ($this->isTestClass($suite)) {
138 $this->column = 0;
139 }
140
141 parent::startTestSuite($suite);
142 }
143
144 function endTestSuite(PHPUnit\Framework\TestSuite $suite) : void {
145 /* print % progress */
146 if ($this->isTestClass($suite)) {
147 if ($this->numTestsRun != $this->numTests) {
148 $colWidth = $this->maxColumn - $this->column;
149 $this->column = $this->maxColumn - 1;
150
151 --$this->numTestsRun;
152 $this->writeProgress(str_repeat(" ", $colWidth));
153 } else {
154 $this->writeNewLine();
155 }
156 }
157
158 parent::endTestSuite($suite);
159 }
160 }
161
162 class TestdoxListener implements PHPUnit\Framework\TestListener
163 {
164 private $groups;
165 private $testdox;
166
167 function __construct() {
168 $this->testdox = new PHPUnit\Util\TestDox\TextResultPrinter("php://stdout", ["testdox"]);
169 $this->groups = new ReflectionProperty("\PHPUnit\Util\TestDox\ResultPrinter", "groups");
170 $this->groups->setAccessible(true);
171 }
172
173 function startTest(PHPUnit\Framework\Test $test) : void {
174 /* always show test class, even if no testdox test */
175 if ($test instanceof \PHPUnit\Framework\TestCase) {
176 if ($test->getGroups() == ["default"]) {
177 $this->groups->setValue($this->testdox, ["default"]);
178 }
179 }
180
181 $this->testdox->startTest($test);
182 $this->groups->setValue($this->testdox, ["testdox"]);
183 }
184
185 public function addError(\PHPUnit\Framework\Test $test, Throwable $t, float $time): void
186 {
187 $this->testdox->addError($test, $t, $time);
188 }
189
190 public function addWarning(\PHPUnit\Framework\Test $test, \PHPUnit\Framework\Warning $e, float $time): void
191 {
192 $this->testdox->addWarning($test, $e, $time);
193 }
194
195 public function addFailure(\PHPUnit\Framework\Test $test, \PHPUnit\Framework\AssertionFailedError $e, float $time): void
196 {
197 $this->testdox->addFailure($test, $e, $time);
198 }
199
200 public function addIncompleteTest(\PHPUnit\Framework\Test $test, Throwable $t, float $time): void
201 {
202 $this->testdox->addIncompleteTest($test, $t, $time);
203 }
204
205 public function addRiskyTest(\PHPUnit\Framework\Test $test, Throwable $t, float $time): void
206 {
207 $this->testdox->addRiskyTest($test, $t, $time);
208 }
209
210 public function addSkippedTest(\PHPUnit\Framework\Test $test, Throwable $t, float $time): void
211 {
212 $this->testdox->addSkippedTest($test, $t, $time);
213 }
214
215 public function startTestSuite(\PHPUnit\Framework\TestSuite $suite): void
216 {
217 $this->testdox->startTestSuite($suite);
218 }
219
220 public function endTestSuite(\PHPUnit\Framework\TestSuite $suite): void
221 {
222 $this->testdox->endTestSuite($suite);
223 }
224
225 public function endTest(\PHPUnit\Framework\Test $test, float $time): void
226 {
227 $this->testdox->endTest($test, $time);
228 }
229 }
230
231 class DebugLogListener implements \PHPUnit\Framework\TestListener
232 {
233 use \PHPUnit\Framework\TestListenerDefaultImplementation;
234
235 private $printLog = false;
236
237 function endTest(PHPUnit\Framework\Test $test, float $time) : void {
238 /* @var $handler \Monolog\Handler\FingersCrossedHandler */
239 $handler = logger()->getHandlers()[0];
240 if ($this->printLog) {
241 $this->printLog = false;
242 $handler->activate();
243 } else {
244 $handler->clear();
245 }
246 }
247
248 function addError(PHPUnit\Framework\Test $test, \Throwable $e, float $time) : void {
249 $this->printLog = true;
250 }
251
252 function addFailure(PHPUnit\Framework\Test $test, PHPUnit\Framework\AssertionFailedError $e, float $time) : void {
253 $this->printLog = true;
254 }
255
256 }