AloFramework documentation
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  • Download

Namespaces

  • Alo
    • Cache
    • CLI
    • Controller
    • Db
    • Exception
    • FileSystem
    • Session
    • Statics
    • Test
    • Validators
    • Windows
  • Controller
  • None
  • PHP

Classes

  • AbstractTester
  • ClassTester
  • FunctionTester
  1 <?php
  2 
  3    namespace Alo\Test;
  4 
  5    use Alo\Exception\TesterException as TE;
  6    use Alo\Statics\Format as F;
  7 
  8    if(!defined('GEN_START')) {
  9       http_response_code(404);
 10       die();
 11    }
 12 
 13    /**
 14     * The abstract tester class
 15     *
 16     * @author     Art <a.molcanovas@gmail.com>
 17     * @package    TestingSuite
 18     * @deprecated Since v1.1
 19     */
 20    abstract class AbstractTester {
 21 
 22       /**
 23        * Defines a parameter as "name"
 24        *
 25        * @var string
 26        */
 27       const P_NAME = 'name';
 28       /**
 29        * Defines a parameter as "arguments"
 30        *
 31        * @var string
 32        */
 33       const P_ARGS = 'args';
 34       /**
 35        * Defines a parameter as "expected outcome"
 36        *
 37        * @var string
 38        */
 39       const P_OUTCOME = 'outcome';
 40       /**
 41        * Defines a parameter as "type"
 42        *
 43        * @var string
 44        */
 45       const P_TYPE = 'type';
 46       /**
 47        * Defines a parameter as "definition"
 48        *
 49        * @var string
 50        */
 51       const P_DEFINITION = 'definition';
 52       /**
 53        * Defines a parameter as "passed"
 54        *
 55        * @var string
 56        */
 57       const P_PASSED = 'passed';
 58       /**
 59        * Defines the test type as "output test"
 60        *
 61        * @var string
 62        */
 63       const T_OUTPUT = 'output';
 64       /**
 65        * Defines the test type as "return test"
 66        *
 67        * @var string
 68        */
 69       const T_RETURN = 'return';
 70       /**
 71        * Defines an outcome as "method/function not callable"
 72        *
 73        * @var string
 74        */
 75       const O_NOT_CALLABLE = 'Not callable';
 76       /**
 77        * Defines a parameter as "start of test"
 78        *
 79        * @var string
 80        */
 81       const P_TEST_START = 'start';
 82       /**
 83        * Defines a parameter as "end of test"
 84        *
 85        * @var string
 86        */
 87       const P_TEST_END = 'end';
 88       /**
 89        * Defines a parameter as "test runtime"
 90        *
 91        * @var string
 92        */
 93       const P_TEST_RUNTIME = 'runtime';
 94       /**
 95        * The test queue
 96        *
 97        * @var array
 98        */
 99       protected $queue;
100       /**
101        * The test results
102        *
103        * @var array
104        */
105       protected $results;
106 
107       /**
108        * Instantiates the tester
109        *
110        * @author Art <a.molcanovas@gmail.com>
111        */
112       function __construct() {
113          $this->queue = $this->results = [];
114       }
115 
116       /**
117        * Runs the tests
118        *
119        * @author Art <a.molcanovas@gmail.com>
120        * @return array Test results
121        */
122       function runTests() {
123          foreach($this->queue as $test) {
124             $this->runTest($test);
125          }
126 
127          return $this->results;
128       }
129 
130       /**
131        * Runs an individual test
132        *
133        * @author Art <a.molcanovas@gmail.com>
134        *
135        * @param array $test The test specs
136        *
137        * @return AbstractTester
138        */
139       protected function runTest(array $test) {
140          $callable = $this->getCallable($test[self::P_DEFINITION][self::P_NAME]);
141 
142          $add = [
143             self::P_DEFINITION => $test[self::P_DEFINITION],
144             self::P_TEST_START => microtime(true)
145          ];
146 
147          if(!is_callable($callable)) {
148             $add[self::P_PASSED]   = false;
149             $add[self::P_OUTCOME]  = self::O_NOT_CALLABLE;
150             $add[self::P_TEST_END] = microtime(true);
151          } else {
152             ob_start();
153             $call                  = call_user_func_array($callable, $test[self::P_DEFINITION][self::P_ARGS]);
154             $ob                    = ob_get_clean();
155             $add[self::P_TEST_END] = microtime(true);
156 
157             $add[self::P_OUTCOME] = $test[self::P_TYPE] == self::T_OUTPUT ? $ob : $call;
158             $add[self::P_PASSED]  = $add[self::P_OUTCOME] == $test[self::P_DEFINITION][self::P_OUTCOME];
159          }
160 
161          $add[self::P_TEST_RUNTIME] = $add[self::P_TEST_END] - $add[self::P_TEST_START];
162          $this->results[]           = $add;
163 
164          return $this;
165       }
166 
167       /**
168        * Returns the callable parameter for call_user_func_array()
169        *
170        * @author Art <a.molcanovas@gmail.com>
171        *
172        * @param string $name Function/method name
173        *
174        * @return array|string
175        */
176       abstract protected function getCallable($name);
177 
178       /**
179        * Adds a test for the output
180        *
181        * @author Art <a.molcanovas@gmail.com>
182        *
183        * @param string $name    The method/function name
184        * @param mixed  $outcome The expected outcome
185        * @param array  $args    The arguments to pass on to the function/method
186        *
187        * @throws TE When the method/function name is invalid
188        * @return AbstractTester
189        */
190       function addOutputTest($name, $outcome, array $args = []) {
191          return $this->addGenericTest(self::T_OUTPUT, $name, $outcome, $args);
192       }
193 
194       /**
195        * Adds a test for the output
196        *
197        * @author Art <a.molcanovas@gmail.com>
198        *
199        * @param string $type    The type of the test - see this class' T_* constants
200        * @param string $name    The method/function name
201        * @param mixed  $outcome The expected outcome
202        * @param array  $args    The arguments to pass on to the function/method
203        *
204        * @throws TE When the method/function name is invalid
205        * @return AbstractTester
206        */
207       protected function addGenericTest($type, $name, $outcome, array $args = []) {
208          if(!is_string($name)) {
209             throw new TE('The name must be a string!', TE::E_NAME_INVALID);
210          } else {
211             $this->queue[] = [
212                self::P_TYPE       => $type,
213                self::P_DEFINITION => [
214                   self::P_NAME    => $name,
215                   self::P_ARGS    => $args,
216                   self::P_OUTCOME => $outcome
217                ]
218             ];
219          }
220 
221          return $this;
222       }
223 
224       /**
225        * Adds a test for the return value
226        *
227        * @author Art <a.molcanovas@gmail.com>
228        *
229        * @param string $name    The method/function name
230        * @param mixed  $outcome The expected outcome
231        * @param array  $args    The arguments to pass on to the function/method
232        *
233        * @throws TE When the method/function name is invalid
234        * @return AbstractTester
235        */
236       function addReturnTest($name, $outcome, array $args = []) {
237          return $this->addGenericTest(self::T_RETURN, $name, $outcome, $args);
238       }
239 
240       /**
241        * Returns the common queue
242        *
243        * @return array
244        */
245       function getQueue() {
246          return $this->queue;
247       }
248 
249       /**
250        * Returns the testing results
251        *
252        * @author Art <a.molcanovas@gmail.com>
253        * @return array
254        */
255       function getResults() {
256          return $this->results;
257       }
258 
259       /**
260        * Returns the test results as plaintext
261        *
262        * @author Art <a.molcanovas@gmail.com>
263        * @return string
264        */
265       function toPlaintextString() {
266          $ret = "";
267 
268          foreach($this->results as $r) {
269             $ret .= $r[self::P_DEFINITION][self::P_NAME] . "\n"
270                     . "\tArgs:\t\t\t" . F::scalarOutput(array_shift($r[self::P_DEFINITION][self::P_ARGS])) . "\n";
271 
272             foreach($r[self::P_DEFINITION][self::P_ARGS] as $arg) {
273                $ret .= "\t\t\t\t" . F::scalarOutput($arg) . "\n";
274             }
275 
276             $ret .= "\tExpected outcome:\t" . F::scalarOutput($r[self::P_DEFINITION][self::P_OUTCOME]) . "\n"
277                     . "\tOutcome:\t\t" . F::scalarOutput($r[self::P_OUTCOME]) . "\n"
278                     . "\tResult:\t\t\t" . ($r[self::P_PASSED] ? 'PASSED' : 'FAILED') . "\n"
279                     . "\tStart time:\t\t" . \timestamp_precise($r[self::P_TEST_START]) . "\n"
280                     . "\tEnd time:\t\t" . \timestamp_precise($r[self::P_TEST_END]) . "\n"
281                     . "\tRuntime:\t\t" . (($r[self::P_TEST_END] - $r[self::P_TEST_START]) * 1000) . "ms\n\n";
282 
283          }
284 
285          return $ret;
286       }
287 
288       /**
289        * Returns the test results in an HTML table
290        *
291        * @author Art <a.molcanovas@gmail.com>
292        * @return string HTML code
293        */
294       function __toString() {
295          $ret = '<table border="1" style="background:#000;color:#fff" cellpadding="2">'
296                 . '<thead>'
297                 . '<tr>'
298                 . '<th>Tested item</th>'
299                 . '<th>Item args</th>'
300                 . '<th>Expected outcome</th>'
301                 . '<th>Outcome</th>'
302                 . '<th>Result</th>'
303                 . '<th>Start time</th>'
304                 . '<th>End time</th>'
305                 . '<th>Runtime</th>'
306                 . '</tr>'
307                 . '</thead>'
308                 . '<tbody>';
309 
310          foreach($this->results as $r) {
311             foreach($r[self::P_DEFINITION][self::P_ARGS] as &$a) {
312                $a = '<span style="color:gold">' . F::scalarOutput($a) . '</span>';
313             }
314 
315             $ret .=
316                '<tr>'
317                .
318                '<td>' .
319                $r[self::P_DEFINITION][self::P_NAME] .
320                '</td>'
321                .
322                '<td><ol style="margin:0;"><li>' .
323                implode('</li><li>', $r[self::P_DEFINITION][self::P_ARGS]) .
324                '</li></ol></td>'
325                .
326                '<td><pre>' .
327                F::scalarOutput($r[self::P_DEFINITION][self::P_OUTCOME]) .
328                '</pre></td>'
329                .
330                '<td><pre>' .
331                F::scalarOutput($r[self::P_OUTCOME]) .
332                '</pre></td>'
333                .
334                '<td style="color:';
335 
336             if($r[self::P_PASSED]) {
337                $ret .= 'lime">PASSED';
338             } else {
339                $ret .= 'red">FAILED';
340             }
341 
342             $ret .= '</td>'
343                     . '<td>' . \timestamp_precise($r[self::P_TEST_START]) . '</td>'
344                     . '<td>' . \timestamp_precise($r[self::P_TEST_END]) . '</td>'
345                     . '<td>' . (($r[self::P_TEST_END] - $r[self::P_TEST_START]) * 1000) . 'ms</td>'
346                     . '</tr>';
347          }
348 
349          return $ret . '</tbody></table>';
350       }
351    }
AloFramework documentation API documentation generated by ApiGen 2.8.0